Update context before template rendering


#1

When a template is going to be rendered, there is a ReqeustHandler that generates its context and then call the render_template() method.

Since the plugin developers are able to create their own custom templates, in order to enrich the representation, they may need to add data customization as well as aspect customization.

For graphical aspect side, is easy, but when you want to add some additional information for a Category or for an Event, the easiest way could be to have a signal that allows plugin developers to update the context adding their data.

Is already in place a mechanism to update a context?


#2

As far as I know I don’t think we have such a mechanism. What are you trying to do exactly? Customize a specific core view from within a plugin? For example, adding some plugin-related things? If that is the case, you could probably use template_hook.


#3

I think he wants to use template customization to append e.g. {{ foo }} to one of the blocks and then provide the data for it himself, without having to add a new template hook in the core.

Sounds like a good idea to me! I remember some discussions in the Flask community on whether the flask signals related to rendering templates should be able to modify the context (iirc. the answer was “no” in the end), but you could simply register an app_context_processor on your plugin’s blueprint and then check e.g. g.rh or request.endpoint to see whether to get custom data and if yes, return a dict with the data you want to add to the template context.


#4

Thanks Adrian, this is exactly what I need, but in my case, I need to add some information into a page only.
Adding an app_context_processor will be executed for each request, it means a potential lack of performance.

If you think this could be an interesting idea, I would suggest calling the signal in the indico.web.views module, WPJinjaMixin class method render_template(), it will simplify our work and I guess the work of many other Indico developer as well.

I’m implementing it already in my local instance. If you agree i can share the code when i finished.

Many thanks again to both.


#5

You really do not have to worry about a function being called on each request. The overhead of that is negligible.

Just check if the blueprint/endpoint/RH matches before running your actual code (that might fetch something from the DB etc.).


But yes, calling a signal in render_template would work as well. I wouldn’t mind reviewing a PR adding such a signal!

I think the overhead is pretty much the same though, since the code to trigger signal handlers will also run every time a signal is handled - and while you could use the class itself as the sender and thus register your signal handler only for specific senders, this might not help that much since there are many places in indico nowadays that can easily use the same WP class!