Jinja (template engine)
Web template engine for Python
- 4 min read
- 3 chapters
Related on Lably
Through Python (programming language), Sandbox (computer security) and Conditional (computer programming)
The Jinja template engine allows customization of tags, filters (for formatting or transforming values), tests (for evaluating conditions), and globals. Also, unlike the Django template engine, Jinja allows the template designer to call functions with arguments on objects. Jinja is the default template engine for Flask, as well as Home Assistant's Automations. It is also used by Ansible, Trac, and Salt. It is also used to make SQL macros, for example for use with dbt.
Features
Some of the features of Jinja are:
- sandboxed execution
- automatic HTML escaping to prevent cross-site scripting (XSS) attacks
- template inheritance
- compiles down to the optimal Python code just-in-time
- optional ahead-of-time template compilation
- easy to debug (for example, line numbers of exceptions directly point to the correct line in the template)
- configurable syntax
Jinja, like Smarty, also ships with an easy-to-use filter system similar to the Unix pipeline.
Sign in to keep reading
2 more chapters are free with a Lably account.
Syntax
The syntax for printing output in Jinja is using the double curly braces, for example {{ Hello, World! }}.
Statements which set variables in jinja or those which do not have an output can be wrapped within {% and %}, using the set keyword. For example {% set foo = 42 %} sets a variable called foo with a value of 42.
Similar to above, comments in jinja can be written using a number sign (#) instead of a percentage (%), for example, {# helpful comment #}.
The syntax for creating a filter in Jinja is a vertical bar (|), for example {{ variable|filter }}. A variable can have multiple filters, for example {{ variable|filter|filter }}).
The syntax for creating a test in Jinja is the keyword is as well as the conditions for evaluating the validity of a test, such as for example {% if variable is divisibleby 10 %}do something{% endif %}).
For loops can be used to iterate over sequences, while retaining their object properties. The following example demonstrates iterating over a list of users with username and password fields.
<span id="mwkQ"></span><span class="cp" id="mwkg">{%</span> <span class="k" id="mwkw">for</span> <span class="nv" id="mwlA">user</span> <span class="k" id="mwlQ">in</span> <span class="nv" id="mwlg">users</span> <span class="cp" id="mwlw">%}</span> <span class="x" id="mwmA"> </span><span class="cp" id="mwmQ">{{</span> <span class="nv" id="mwmg">user.username</span> <span class="cp" id="mwmw">}}</span> <span class="x" id="mwnA"> </span><span class="cp" id="mwnQ">{{</span> <span class="nv" id="mwng">user.password</span> <span class="cp" id="mwnw">}}</span> <span class="cp" id="mwoA">{%</span> <span class="k" id="mwoQ">endfor</span> <span class="cp" id="mwog">%}</span>Although break and continue are not allowed inside loops, sequences can be filtered.
Example
Here is a small example of a template file example.html.jinja:
<span id="mwsw"></span><span class="cp" id="mwtA"><!DOCTYPE html></span> <span class="p" id="mwtQ"><</span><span class="nt" id="mwtg">html</span><span class="p" id="mwtw">></span> <span class="p" id="mwuA"><</span><span class="nt" id="mwuQ">head</span><span class="p" id="mwug">></span> <span class="p" id="mwuw"><</span><span class="nt" id="mwvA">title</span><span class="p" id="mwvQ">></span><span class="cp" id="mwvg">{{</span> <span class="nv" id="mwvw">variable</span><span class="o" id="mwwA">|</span><span class="nf" id="mwwQ">escape</span> <span class="cp" id="mwwg">}}</span><span class="p" id="mwww"></</span><span class="nt" id="mwxA">title</span><span class="p" id="mwxQ">></span> <span class="p" id="mwxg"></</span><span class="nt" id="mwxw">head</span><span class="p" id="mwyA">></span> <span class="p" id="mwyQ"><</span><span class="nt" id="mwyg">body</span><span class="p" id="mwyw">></span> <span class="cp" id="mwzA">{%</span>- <span class="k" id="mwzQ">for</span> <span class="nv" id="mwzg">item</span> <span class="k" id="mwzw">in</span> <span class="nv" id="mw0A">item_list</span> <span class="cp" id="mw0Q">%}</span> <span class="cp" id="mw0g">{{</span> <span class="nv" id="mw0w">item</span> <span class="cp" id="mw1A">}}{%</span> <span class="k" id="mw1Q">if</span> <span class="k" id="mw1g">not</span> <span class="nb" id="mw1w">loop</span><span class="nv" id="mw2A">.last</span> <span class="cp" id="mw2Q">%}</span>,<span class="cp" id="mw2g">{%</span> <span class="k" id="mw2w">endif</span> <span class="cp" id="mw3A">%}</span> <span class="cp" id="mw3Q">{%</span>- <span class="k" id="mw3g">endfor</span> <span class="cp" id="mw3w">%}</span> <span class="p" id="mw4A"></</span><span class="nt" id="mw4Q">body</span><span class="p" id="mw4g">></span> <span class="p" id="mw4w"></</span><span class="nt" id="mw5A">html</span><span class="p" id="mw5Q">></span>and templating code:
<span id="mw6Q"></span><span class="kn" id="mw6g">from</span><span class="w" id="mw6w"> </span><span class="nn" id="mw7A">jinja2</span><span class="w" id="mw7Q"> </span><span class="kn" id="mw7g">import</span> <span class="n" id="mw7w">Template</span> <span class="k" id="mw8A">with</span> <span class="nb" id="mw8Q">open</span><span class="p" id="mw8g">(</span><span class="s2" id="mw8w">"example.html.jinja"</span><span class="p" id="mw9A">)</span> <span class="k" id="mw9Q">as</span> <span class="n" id="mw9g">f</span><span class="p" id="mw9w">:</span> <span class="n" id="mw-A">tmpl</span> <span class="o" id="mw-Q">=</span> <span class="n" id="mw-g">Template</span><span class="p" id="mw-w">(</span><span class="n" id="mw_A">f</span><span class="o" id="mw_Q">.</span><span class="n" id="mw_g">read</span><span class="p" id="mw_w">())</span> <span class="nb" id="mwAQA">print</span><span class="p" id="mwAQE">(</span><span class="n" id="mwAQI">tmpl</span><span class="o" id="mwAQM">.</span><span class="n" id="mwAQQ">render</span><span class="p" id="mwAQU">(</span> <span class="n" id="mwAQY">variable</span> <span class="o" id="mwAQc">=</span> <span class="s2" id="mwAQg">"Value with <unsafe> data"</span><span class="p" id="mwAQk">,</span> <span class="n" id="mwAQo">item_list</span> <span class="o" id="mwAQs">=</span> <span class="p" id="mwAQw">[</span><span class="mi" id="mwAQ0">1</span><span class="p" id="mwAQ4">,</span> <span class="mi" id="mwAQ8">2</span><span class="p" id="mwARA">,</span> <span class="mi" id="mwARE">3</span><span class="p" id="mwARI">,</span> <span class="mi" id="mwARM">4</span><span class="p" id="mwARQ">,</span> <span class="mi" id="mwARU">5</span><span class="p" id="mwARY">,</span> <span class="mi" id="mwARc">6</span><span class="p" id="mwARg">]</span> <span class="p" id="mwARk">))</span>
This produces the HTML string:
<span id="mwAR0"></span><span class="cp" id="mwAR4"><!DOCTYPE html></span> <span class="p" id="mwAR8"><</span><span class="nt" id="mwASA">html</span><span class="p" id="mwASE">></span> <span class="p" id="mwASI"><</span><span class="nt" id="mwASM">head</span><span class="p" id="mwASQ">></span> <span class="p" id="mwASU"><</span><span class="nt" id="mwASY">title</span><span class="p" id="mwASc">></span>Value with <span class="ni" id="mwASg"><</span>unsafe<span class="ni" id="mwASk">></span> data<span class="p" id="mwASo"></</span><span class="nt" id="mwASs">title</span><span class="p" id="mwASw">></span> <span class="p" id="mwAS0"></</span><span class="nt" id="mwAS4">head</span><span class="p" id="mwAS8">></span> <span class="p" id="mwATA"><</span><span class="nt" id="mwATE">body</span><span class="p" id="mwATI">></span> 1, 2, 3, 4, 5, 6 <span class="p" id="mwATM"></</span><span class="nt" id="mwATQ">body</span><span class="p" id="mwATU">></span> <span class="p" id="mwATY"></</span><span class="nt" id="mwATc">html</span><span class="p" id="mwATg">></span>
Note the minus sign (-) after the tag {%: If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed.

