Getting Started with Jinja ¶
Jinja is a fast, expressive, and extensible templating engine for Python applications.
Jinja includes a lot of functionalities, such as:
- Template inheritance and inclusion;
- Defining and importing macros within templates;
- Security mechanisms to prevent XSS attacks;
- A sandboxed environment that can safely render untrusted templates;
- Extensible filters, tests, functions, and even syntax.
A Jinja template is simply a text file. Jinja doesn’t require a specific
extension, but it’s common to use .j2
or .jinja
to make it easier for
some IDEs.
There are a few kinds of delimiters. The default Jinja delimiters are configured as follows:
{% ... %}
for Statements{{ ... }}
for Expressions to print to the template output{# ... #}
for Comments not included in the template output
1{# This is an example of a comment. #}
2
3{#
4 You can use this syntax
5 to write multiline comments
6 as well.
7#}
VARIABLES ¶
1{# You have the option to access variables from the context passed to the template #}
2
3{{ foo }}
4
5{#
6 Additionally, you can use a dot (.) to access attributes of a variable or
7 use Python syntax, using []
8#}
9
10{{ foo.bar }}
11{{ foo['bar'] }}
12
13{# Within the template, you can define variables as well #}
14
15{% set name = "Magdiel" %}
16{{ name }}
Loops ¶
1<h1>Members</h1>
2<ul>
3{% for user in users %}
4 <li>{{ user.username }}</li>
5{% endfor %}
6</ul>
7
8
9<div>
10{% for key, value in my_dict.items() %}
11 <p>{{ key }}</p> - <p>{{ value }}</p>
12{% endfor %}
13</div>
14
15
16<div>
17{% for idx, url in enumerate(urls) %}
18 <a href="{{ url }}">Go to url {{ idx + 1 }}</a>
19{% endfor %}
20</div>
Conditionals ¶
The if statement in Jinja is similar to the if statement in Python. It is commonly used to check if a variable is defined, not empty, and not false in its most basic form.
1{% if users %}
2<ul>
3{% for user in users %}
4 <li>{{ user.username }}</li>
5{% endfor %}
6</ul>
7{% endif %}
8
9
10{# For multiple branches, elif and else can be used like in Python. #}
11
12
13{% if message.status == "error" %}
14 <p class="text-red-400">{{ message.content }}</p>
15{% elif message.status == "success" %}
16 <p class="text-green-400">{{ message.content }}</p>
17{% else %}
18 <p class="text-blue-400">{{ message.content }}</p>
19{% endif %}
Template Inheritance ¶
One of the most powerful features of Jinja is template inheritance. You can create a base layout with predefined blocks that you can extend in another file and override with your own content.
1{# file: base.html.j2 #}
2
3<!DOCTYPE html>
4<html lang="en">
5<head>
6 {% block head %}
7 <meta charset="UTF-8">
8 <meta name="viewport" content="width=device-width, initial-scale=1.0">
9 <title>{% block title %}{% endblock title %} - Learning Jinja</title>
10 {% endblock head %}
11</head>
12<body>
13 <main>
14 {% block content %}{% endblock %}
15 {# the endblock tag doesn't need the name of the block #}
16 </main>
17</body>
18</html>
19
20
21
22{# file: child.html.j2 #}
23
24{% extends "base.html.j2" %}
25
26{% block head %}
27 {{ super() }}
28 <script>
29 console.log("There's a console.log here")
30 </script>
31{% endblock %}
32
33{% block title %}Home{% endblock %}
34
35{% block content %}
36 <h1>Index</h1>
37 <p>Welcome to my home homepage.</p>
38{% endblock %}
39
40
41
42{# RESULT #}
43
44<!DOCTYPE html>
45<html lang="en">
46<head>
47 <meta charset="UTF-8">
48 <meta name="viewport" content="width=device-width, initial-scale=1.0">
49 <title>Home - Learning Jinja</title>
50 <script>
51 console.log("There's a console.log here")
52 </script>
53</head>
54<body>
55 <main>
56 <h1>Index</h1>
57 <p>Welcome to my home homepage.</p>
58 </main>
59</body>
60</html>
Including Content ¶
You can include content from another template on your current template using
the {% include "template/path" %}
tag.
1{# file: footer.html.j2 #}
2
3<footer>
4 <p>© 2024 - John Doe</p>
5</footer>
6
7
8
9{# file: index.html.j2 #}
10...
11<body>
12 <main>
13 <h1>Hi! I'm John Doe!</h1>
14 </main>
15 {% include "footer.html.j2" %}
16</body>
17...
18
19
20
21{# RESULT #}
22
23...
24<body>
25 <main>
26 <h1>Hi! I'm John Doe!</h1>
27 </main>
28 <footer>
29 <p>© 2024 - John Doe</p>
30 </footer>
31</body>
32...
Variables passed to the main template can also be used in the include, as the included template has access to the context of the main template.
1{# file: greetings.html.j2 #}
2
3<p>I'm the {{ name }} and i like to {{ hobby }}.</p>
4
5
6
7{# file: index.html.j2 #}
8
9{% set name = "Captain Nemo" %}
10{% set hobby = "navigate through the depths of the ocean" %}
11
12<div>
13 {% include "greetings.html.j2" %}
14</div>
15
16
17
18{# RESULT #}
19
20<div>
21 <p>I'm the Captain Nemo and i like to navigate through the depths of the ocean.</p>
22</div>
Macros ¶
Macros are basically like functions in another languages. You can define macros with or without arguments and reuse them in various parts of your template.
1{% macro input(value="", type="text", placeholder="") -%}
2 <input type="{{ type }}" value="{{ value }}" placeholder="{{ placeholder }}">
3{%- endmacro %}
4
5<p>{{ input(placeholder="Your username") }}</p>
6<p>{{ input(type="password") }}</p>
Official Documentation ¶
To learn more, access the official documentation.