Home > Mobile >  Jinja2 Custom Filter for templates
Jinja2 Custom Filter for templates

Time:07-06

I need a single template, so I choose not to create a specific environment. Jinja creates an environment under the hood, so I attempted to add the filter to that environment. As in the following example:

TEMPLATE = """
{{items|round_to_even}}
"""
def main():
    template = Template(TEMPLATE, trim_blocks=True, lstrip_blocks=True)
    template.environment.filters.update(
        {
            'round_to_even': lambda x: x if x % 2 == 0 else x 1,
        }
    )
    print(template.render(
        items=[1, 2, 3],
    ))
    return 0


if __name__ == '__main__':
    main()

I was expecting an output of [2, 2, 4] or something along these lines; instead, I got an error:

jinja2.exceptions.TemplateAssertionError: No filter named 'round_to_even'.

I tried looking through the source code, but couldn't find a way that looked intended to add filters. What would be the way to add custom filters to a template?

CodePudding user response:

The way to do this is to modify the global FILTERS dictionary which Jinja keeps.

>>> from jinja2 import Template
>>> from jinja2.filters import FILTERS
>>> FILTERS['increment'] = lambda x: x 1
>>> print(Template('{{number|increment}}').render(number=15))
16

Please note that the function has to be added to the FILTERS dictionary before the Template is created. This is because every template makes an environment behind the scenes, which copies the global FILTERS on instantiation, but doesn't stay updated.

Additionally, this work flow may cause problems if you are using environments, since you're modifying global variables. Use with caution.

This answer is based on https://stackoverflow.com/a/67384801/4331885

  • Related