Explain Codes LogoExplain Codes Logo

Call a python function from jinja2

python
jinja2
flask
functions
Nikita BarsukovbyNikita Barsukov·Jan 30, 2025
TLDR

To invoke a Python function from a Jinja2 template, inject the function into the rendering context when calling render_template in Flask:

# Define function (the greeter of a thousand hellos!) def greet(name): return f"Hello, {name}" # Pass function to our grand template return render_template('template.html', greet=greet) # Now, greet away all day in the template! # {{ greet('World') }}

This snippet Registers greet as a function, Passes it into template.html, and finally Calls it within the Jinja2 template.

Advanced utilization

Functions on a global tour

Register functions globally to make them universally accessible without redefining in every template:

# Your function gets its global Visa app.jinja_env.globals['greet'] = greet

With this global setup, greet can be invoked anywhere in your templates.

Flask context processors: The grocery-getters of data

Use Flask context processors to supply functions or variables automatically available in all your templates context:

@app.context_processor def utility_processor(): def format_price(amount, currency="$"): return f"{currency}{amount:0.2f}" #Prices neatly packed with two decimal points! return dict(format_price=format_price) # utility_processor: your one-stop function shop!

Embracing Python's 'import' trait

For cleaner organization, have functions defined in separate files or modules and import them:

# utilities.py def compute_discount(price, discount): return price * (1 - discount) # Price cut!

In your main Python file:

from utilities import compute_discount # Import to duty-free use! app.jinja_env.globals['compute_discount'] = compute_discount

Choosy templates choose specific functions

You can also Pass non-global functions or variables to specific templates for exclusive access:

return render_template('sales.html', compute_discount=compute_discount)

Filters: Jinja2's little helper

Harness the power of custom Jinja filters.

@app.template_filter('topthree') def topthree_filter(sequence): return sequence[:3] # Top three, coming up!

Template loaders to the rescue

Leverage the FileSystemLoader to load templates after adding function references.

from jinja2 import Environment, FileSystemLoader # Jinja2 Environment, Assemble! env = Environment(loader=FileSystemLoader('/path/to/templates')) env.globals['greet'] = greet template = env.get_template('my_template.html') print(template.render()) # 'Hello, my_template.html!'

Pssst...Which version are you on?

Ensure your functions play nice with your Jinja2 version. Compatibility matters!

import jinja2 print(jinja2.__version__) # Compatibility Check: Who are you again?

Practical scenarios and pitfalls

Generating content dynamically

You can generate dynamic content by calling functions that manipulate data in templates:

<ul> {% for user in users %} <li>{{ get_user_role(user) }} <!-- Who are you, dear user? --> {% endfor %} </ul>

Caching for performance

Call complex functions sparingly. Consider caching function results to serve multiple same-requests.

Jinja's template-side manners

Flask follows the principle: Don't repeat yourself (DRY). So, busying your templates with heavy functions may cause them to fail silently or spit out cryptic errors.

Separation of duties

Business logic and presentation logic don't mix well. Minimize logic in your Jinja2 templates and let Python functions handle the computational heavy-lifting.