Embed custom filter definition into jinja2 template?

23,850

Solution 1

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

Solution 2

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


@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.

Share:
23,850

Related videos on Youtube

Daisy Sophia Hollman
Author by

Daisy Sophia Hollman

I have been involved in the ISO-C++ standard committee since 2016. He has been a part of a number of different papers in that time, including mdspan, atomic_ref, and—most prominently—executors and futures. Since finishing my Ph.D. in computational quantum chemistry at the University of Georgia in 2013, I have mostly worked on programming models for computational science, data science, and related fields. I joined Sandia National Labs in 2014 and have worked on several different programming models projects since then. I like to make computers do cool things. In addition to my work on C++, I like Python, Ruby, Markdown, Mathematica, and generally any other language that brings something interesting to the table.

Updated on May 06, 2021

Comments

  • Daisy Sophia Hollman
    Daisy Sophia Hollman about 3 years

    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.

  • Tanmay Baranwal
    Tanmay Baranwal about 5 years
    Any idea on how to remove all the old filters?
  • flazzarini
    flazzarini about 5 years
    If you mean removing all existing default filters you could simple replace env.filters with an empty dictionary by doing env.filters = {}. Not sure however why would want to do that.
  • Tanmay Baranwal
    Tanmay Baranwal about 5 years
    Sorry, I meant all the old "custom" filters. But I found that Jinja environment sets up the basic filters explicitly, so can't assign to empty dictionary.
  • superloopnetworks
    superloopnetworks over 3 years
    @flazzarini How do you call upperstring and feed in the variable "input"? If I wanted a custom filter for boolean, how do I return the variable true/false that I pass in?
  • flazzarini
    flazzarini over 3 years
    Not sure if I understand your question correctly, but If you would like to define a filter that would return a boolean type you could write something here to transform any given strings into boolean values using a jinja2 filter.