1. Template Middlewares
Problem: Plugins must have ways to inject template-specific variables on template render
Following Django's example, simple middlewares system could be put in place for plugins to use. Middleware would be provided with current request object, template name that Misago is going to render and template context that will be used in rendering. Middleware method would return either nothing or changed template context that Misago would use in rendering. Then second pass will be done. This time middlewares will be asked if they want to use different template file and first middleware to return string with new template name will break the loop and cause new template to render.
Such middlewares system is easy to implement and quick to run, so I don't see many troubles from including it even in 0.3 release. Adding hooks to templates for plugins to use is different story however. In theory I could start with most basic hooks that would allow extensions to add custom nav links to forum's header and footer nav's and then include new hooks as people request them.
Update
And so template middleware framework is already in develop branch. In order to use it write your own middleware and make it known to Misago by including path to it in 'TEMPLATE_MIDDLEWARES' setting.
Example middleware looks like this:
class ExampleMiddleware(object):
def process_context(self, theme, templates, context):
"""
Optional, use this method to modify context that will
be passed to target template when its rendered.
Should return dict-like object or nothing.
"""
pass
def process_template(self, theme, templates, context):
"""
Optional, use this method to change template that will be rendered
by Misago. Those methods are called until one returns string or
tuple with template names.
Should return string, tuple or nothing.
"""
pass
Both methods are optional. process_context
is called before process_template
.
Middlewares always take three arguments:
- theme - theme helper, allows middlewares to render templates into other templates context dicts.
- templates - string or tuple with templates that Misago is going to render using passed context. You can use this to limit your middleware only to specific pages.
- context - template context, depending on origin this will be dictionary or dict-like object. It's complete context that was ran trough context_processors, and so it can be used as surrogate for
request
object for your middleware.
Available Hooks
Currently Misago implements following hooks for those interested in playing with template middlewares:
base.html - Layout Container
- hook_append_extra - Right before closing
</body>
tag. Allows for adding extra site-wide scripts or fixed html.
layout.html - Forum Layout
- hook_primary_menu_prepend - In primary menu after "Board Index" link.
- hook_primary_menu_append - In primary menu after all other links.
- hook_foot_menu_prepend - In footer menu before "Forum Map" link.
- hook_foot_menu_append - In footer menu after "Forum Map" link.
- hook_guest_menu_prepend - In guest menu before "Sign In" link.
- hook_guest_menu_append - In guest menu after"Sign In" link.
- hook_user_menu_prepend - In user menu between "Alers" link and Username.
- hook_user_menu_append - In guest menu before "Sign Out" link.
- hook_credits_side - Right side of forum credits. This forum uses this hook for Github and PayPal buttons
index.html - Board Index
- hook_above_forum_home - Above everything else.
- hook_below_forum_home - Below everything else.
- hook_above_home_forums_list - Above forums list.
- hook_below_home_forums_list - Below forums list.
- hook_above_home_sidepanel - Above sidepanel.
- hook_after_home_sidepanel_ranks_online - In sidepanel, under "Ranks Online".
- hook_after_home_sidepanel_popular_threads - In sidepanel, under "Popular Threads".
- hook_after_home_sidepanel_forum_stats - In sidepanel, under forum statistics.
- hook_below_home_sidepanel - In sidepanel, below everything else.
Every hook is defautly empty unicode string. To display something in this hook, simply append or prepend unicode string to its contents. Those variables are trusted in order to allow your plugins to render HTML. For this reason middlewares are provided with theme helper that comes with render_to_string(template, variables)
method that allows you to render other templates into hook variables.
Naturally you are not limited to or forced to do adding html to hooks. If you want to, you can instead modify other variables in context and then in make Misago use different template to render page.
Finally, instead of checking for template name in templates argument, you can check context for presence of hook variable. Standard hooks will be always included into template context for you to know what hooks are currently available.