I'm trying to render a jinja2 template in my service (not using flask, just pure jinja2 and constructing a jinja2 Environment.
Let's say I have the following filter defined
import jinja2
@jinja2.contextfilter
def my_function(context):
if context.get('my_var'):
return "hello"
else:
return "world"
Super simplified example, but the point of it is that I have some logic that conditionally returns a value based on some variable passed into the context.
Also, I'm using jinja2 2.11 or something like that, which is why I'm using @contextfilter
instead of @pass_context
.
I've added this filter to my environment using env.filters['my_function'] = my_function
In rendering the template, I'm calling
template = env.get_template('my_template.html')
template.render({'my_var': 'some_value'})
where the template might look something like
... some html here
{{ my_function }}
... some more html
This doesn't actually return "hello", and instead just is empty/blank.
I managed to get it by passing in a dummy variable
@jinja2.contextfilter
def my_function(context, value):
.... code is the same
And then in the template, I call it with {{ 'hi' | my_function }}
. But obviously this is just a hack and not very desirable.
So my question is, how can I call a jinja2 filter function that only takes the context in as an argument? I've tried {{ my_function() }}
which returns the error UndefinedError: 'my_function' is undefined
, and {{ | my_function }}, which returns the error
TemplateSyntaxError: unexpected '|'`
Or is there some other jinja2 construct I should be using?
Edit: my suspicion is that jinja2 uses the |
to identify a filter vs a variable, and since I don't have |
, then it tries to just render the variable my_function
from the context, and since it doesn't exist in the context, it just outputs an empty string.
CodePudding user response:
Jinja2 calls these kind of functions global functions (like range()
), not filters. Just change filters
to globals
in this line:
env.globals['my_function'] = my_function
And then you can call your function in the templates: {{ my_function() }}
.