Daisy Sophia Hollman
Daisy Sophia Hollman

Reputation: 6286

Embed custom filter definition into jinja2 template?

I'm writing some Jinja2 templates that I'd like to be able to reuse as painlessly as possible in tangentially related projects. I have a set of custom convenience filters that I'd like the templates to "carry around" with them. Is there a Jinja2 syntax for embedding filter definitions into a template itself? Or a mechanism for embedding any kind of pure Python function into a Jinja2 template that can act on variables passed into the template? I used to use mako, and there it was trivial to do this, but templating LaTeX in mako is painful because of the lack of custom syntax, so I had to make the switch.

Upvotes: 26

Views: 44899

Answers (2)

vikas soni
vikas soni

Reputation: 588

There is an easy way to add custom filters in jinja2 template. FILTERS is the dictionary containing all filters that we can use to render the template. However, we can add more filters to it.

Here is a quick example to add new filters to it.


from jinja2 import Template
from jinja2.filters import FILTERS, environmentfilter


// Remove the decorator in the next line if using version 3.1.0 or higher, read below
@environmentfilter
def do_reverse_by_word(environment, value, attribute=None):
    """
    custom max calculation logic
    """
    if attribute:
        return [list(reversed(i.get(attribute).split())) for i in value]

    return list(reversed(value.split()))


FILTERS["reverse_by_word"] = do_reverse_by_word
print(Template("{{ name | reverse_by_word }}").render({"name": "Stack Overflow"}))
print(Template("{{ names | reverse_by_word(attribute='name') }}").render({"names": [{"name": "Stack Overflow"}, {"name": "Stack Exchange"}]}))


Outputs

['Overflow', 'Stack']
[['Overflow', 'Stack'], ['Exchange', 'Stack']]

please comment below in case you've more complex use cases. I'll be happy to answer all your queries.

Update (tested with version 3.1.2): The decorator environmentfilter is no longer needed (and does not exist anymore). Source

Upvotes: 21

flazzarini
flazzarini

Reputation: 8171

There is NO way you can embed python directly into a Jinja2 Template, the way that I know of is to define in your application and add them to your Jinja2 environment instance. Like the following example taken from https://jinja.palletsprojects.com/en/2.11.x/api/#writing-filters.

import jinja2

loader = jinja2.FileSystemLoader('/tmp')
env = jinja2.Environment(autoescape=True, loader=loader)

def upperstring(input):
    """Custom filter"""
    return input.upper()

env.filters['upperstring'] = upperstring
temp = env.get_template('template.html')
temp.render(name="testing")

Here the Template I am using

{{ name | upperstring }}

Result is this

TESTING

Upvotes: 45

Related Questions