Jinja2 Quick Reference


This section provides an overview of the syntax and some of the commonly used features of the Jinja2 templating language. For more detailed information, refer to the official Jinja2 documentation.

As the template engine is very flexible, the configuration from the PathcoreFlow application can be slightly different from the code presented here in terms of delimiters and behavior of undefined values. If you encounter any anomalies, contact our support team.

Basic Syntax

A template contains variables and/or expressions, which get replaced with values when a template is rendered; and tags, which control the logic of the template.

There are a few kinds of delimiters configured as follows:

{% ... %} for Statements
{{ ... }} for Expressions to print to the template output
{# ... #} for Comments not included in the template output

Variables

Variables may have attributes or elements on them you can access. See the Placeholder Reference for details.

You can use a dot (.) to access attributes of a variable in addition to the standard subscript ([]) syntax.

The following lines do the same thing:

{{ folder.image }}
{{ folder['image'] }}

It’s important to know that the outer two curly braces are not part of the variable, but the print statement. If you access variables inside tags, don't put the braces around them. If a variable or attribute does not exist, you will get back an undefined value.

Filters

Variables can be modified by filters. Filters are separated from the variable by a pipe symbol (|) and may have optional arguments in parentheses. Multiple filters can be chained. The output of one filter is applied to the next.

For example, {{ name|striptags|title }} will remove all HTML Tags from variable "name" and title-case the output (i.e., title(striptags(name))).

Filters that accept arguments have parentheses around the arguments, just like a function call. For example: {{ listx|join(', ') }} will join a list with commas (i.e., str.join(', ', listx)).

The List of Builtin Filters in the official Jinja2 documentation describes all the builtin filters.

Tests

Beside filters, there are also so-called “tests” available. Tests can be used to test a variable against a common expression. To test a variable or expression, you add is plus the name of the test after the variable. For example, to find out if a variable is defined, you can do name is defined, which will then return true or false depending on whether name is defined in the current template context.

Tests can accept arguments, too. If the test only takes one argument, you can leave out the parentheses. For example, the following two expressions do the same thing:

{% if loop.index is divisibleby 3 %}
{% if loop.index is divisibleby(3) %}

The List of Builtin Tests in the official Jinja2 documentation describes all the builtin tests.

Comments

To comment out part of a line in a template, use the comment syntax which is {# ... #}. This is useful to comment out parts of the template for debugging or to add information for other template designers or yourself:

{# note: commented-out template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}

Control Structures

A control structure refers to all those things that control the flow of a program - conditionals (i.e., if/elif/else), for-loops, as well as things like macros and blocks. Control structures appear inside {% ... %} blocks.

For

Loop over each item in a sequence. For example, to display a list of image names provided in the selected folder:

<h2>Images</h2>
<ul>
{% for im in folder.images %}
<li>{{ im.name|e }}</li>
{% endfor %}
</ul>

As variables in templates retain their object properties, it is possible to iterate over containers like dict:

<dl>
{% for key, value in folder.fields.items() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}
</dl>
The "e" in the above examples is an alias for the builtin escape filter. The escape filter converts the characters &, <, >, ‘, and ” in a string to HTML-safe sequences. Use this if you need to display text that might contain such characters.

Note, however, that dicts are not ordered; so you might want to use the dictsort filter.

Inside of a for-loop block, you can access some special variables:

VariableDescription
loop.indexThe current iteration of the loop. (1 indexed).
loop.index0The current iteration of the loop. (0 indexed).
loop.revindexThe number of iterations from the end of the loop (1 indexed).
loop.revindex0The number of iterations from the end of the loop (0 indexed).
loop.firstTrue if first iteration.
loop.lastTrue if last iteration.
loop.lengthThe number of items in the sequence.
loop.cycleA helper function to cycle between a list of sequences. See the explanation below.
loop.depthIndicates how deep in a recursive loop the rendering currently is. Starts at level 1.
loop.depth0Indicates how deep in a recursive loop the rendering currently is. Starts at level 0.

Unlike in Python, it’s not possible to break or continue in a loop. You can, however, filter the sequence during iteration, which allows you to skip items. The following example skips images with the name "test":

{% for im in folder.images if not im.name == 'test' %}
<li>{{ im.name|e }}</li>
{% endfor %}

If no iteration took place because the sequence was empty or the filtering removed all the items from the sequence, you can render a default block by using else:

<ul>
{% for im in folder.images %}
<li>{{ im.name }}</li>
{% else %}
<li><em>No image found</em></li>
{% endfor %}
</ul>

If

In the simplest form, you can use the If statement to test if a variable is defined, not empty and not false:

{% if report_signed_by %}
<div class="signature">
<img src="{{ report_signed_by.signature }}" />
<p>Signed by {{ report_signed_by.name }} at {{ report_signed_at }}</p>
</div>
{% endif %}