Reputation: 28971
I'm writing a custom jinja2
extension to use in flask
applications and I'm looking for a way to access the templates context data using the tag I'm implementing. That is, I want the extension tag to use context params passed into the template:
@app.route('/users/<user_id>')
def user_page(user_id):
...
return render_template('users/index.html', user_id=user_id, active=True)
The template:
<!-- I want this tag to see the value of user_id and active -->
{% my_jinja2_tag %}
I know I can render the context variable using {{ user_id }}
, but what I'm looking for is a way to inspect the context of the template rendering a custom jinja2 extension. Is that doable? thanks.
Upvotes: 3
Views: 1672
Reputation: 2482
Yes, it's possible using jinja2.nodes.ContextReference()
. See the API reference here.
Relax, I'm going to guide you through it. :)
First the extension:
class ActiveCheckerExtension(jinja2.ext.Extension):
"""
This will give us a {% check_active %} tag.
"""
template = 'Active is : %s'
tags = set(['check_active'])
def _render_tag(self, context, caller):
return jinja2.Markup(self.template % unicode(context['active']))
def parse(self, parser):
ctx_ref = jinja2.nodes.ContextReference()
lineno = next(parser.stream).lineno
node = self.call_method('_render_tag', [ctx_ref], lineno=lineno)
return jinja2.nodes.CallBlock(node, [], [], [], lineno=lineno)
Then let's add it to Flask's jinja2.
app.jinja_env.add_extension(ActiveCheckerExtension)
Now in your template, you can do:
{% check_active %}
Make sure active
is defined in all the templates you add the tag to, or else you'll get a KeyError
because the context won't have that template variable.
Upvotes: 3