An Introduction to Jinja

Jeff Manning
Chartboost Engineering
3 min readApr 3, 2020

--

Jinja is a templating language for Python, commonly found in Flask projects. To quote the official documentation, Jinja provides a sandboxed execution environment, a powerful and automated HTML escaping system to prevent XSS attacks, and very usefully, template inheritance.

A Jinja document contains expressions and variables, all of which will get replaced when a document is rendered. Let’s setup a quick example to get you up and running.

# run.pyfrom flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template('hello.html')
<!-- templates/hello.html --><h1>Hello, World!</h1>
export FLASK_APP=run.pypip install flask
flask run

This should get your Flask application up and running. If you run into issues, I point you towards the excellent official Flask quick start guides. Navigating to http://localhost:5000/ will now show you the output of our html document,

Hello, World!

Two major components to Jinja templates are expressions and statements. Lets experiment iterating over a dictionary and a list that are defined in the Python code.

# run.pyfrom flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
a_list = [1,2,3,4,5]
a_dict = {'a': 1, 'b': 2, 'c': 3}
return render_template('hello.html', a_list=a_list, a_dict=a_dict)

We’ve now passed our list and dictionary to the Jinja template. We can iterate and render them as such:

<!-- templates/hello.html --><h1>Hello, World!</h1>{# iterate a list #}
{% for item in a_list %}
<li>{{ item }}</li>
{% endfor %}
<hr>{# iterate a dict #}
{% for key, value in a_dict.items() %}
Key: {{ key }}, Value: {{ value }}
{% endfor %}

Hello, World!

1 2 3 4 5
Key: a, Value: 1 Key: b, Value: 2 Key: c, Value: 3

Pretty cool, right? We can also apply filters in the Jinja template!

{% for item in a_list and item % 2 == 0 %}
{{ item }} is even!
{% endfor %}

2 is even! 4 is even!

Note that unlike Python, you can not continue or break out of a loop.

It is also possible to set variables within the Jinja template, bypassing Python altogether.

{% set a_list = [9,8,7,6,5] %}{% for item in a_list %}
{{ item }}
{% endfor %}

9 8 7 6 5

Jinja also supports macros, take a look:

{% macro double(num) %}
{% if num is number %}
{{ num * 2 }}
{% else %}
{{ num }} is not a number!
{% endif %}
{% endmacro %}
{{ double(2) }}
{{ double(5) }}
{{ double('Chartboost is awesome') }}

4 10 Chartboost is awesome is not a number!

This can be incredibly useful to enforcing do-not-repeat-yourself in your codebase.

Finally, Jinja supports template inheritance. This is an incredibly powerful feature that allows you to build a base layout and inject content from other elements. First, let’s define a new file, “world.html”:

<!-- world.html --><i>{% block content %}{% endblock %}</i>

Simple enough, it looks for the “content” block and italicizes it. Back in “hello.html”:

<!-- hello.html -->{% extends "world.html" %}
{% block content %} This is italicized! {% endblock %}

Here’s some text from world.html! This is italicized!

Notice we “imported” the text from “world.html”, and also inserted our string “This is italicized!” into “world.html”.

Jinja is an incredibly powerful tool that can be used to provide dynamic components to your web application. At Chartboost, it has been used to dramatically decrease code bloat and promote DRY principles while refactoring legacy applications.

--

--