Conditionals
You can dynamically change the result of your template based on input data using Jinja's conditionals: their syntax resembles Python's if
statement.
The simplest conditional looks like this:
{% if variable condition value %}
# do something
{% endif %}
Let's explore them using an example. Imagine that you have an e-commerce website and you don't want to charge shipping costs if the order's total amount is greater or equal to €50
(ignoring the currency, for simplicity's sake).
{%- if order_amount >= 50 -%}
No shipping costs.
{%- endif -%}
If you want to follow along and try out the examples yourself:
- create a folder called
jinja-templates
- save the above snippet to a file in that folder (for example, named
jinja-templates/conditionals.txt
), and - follow the next steps to render your template
Enter the Python 3 interpreter (this assumes that you have a working Python 3 installation):
$ python3
import Jinja and point it to the jinja-templates
folder you just created
>>> from jinja2 import Environment, FileSystemLoader
>>> env = Environment(loader=FileSystemLoader("jinja-templates/"))
Finally, render the template providing a value for order_amount
>>> tpl = env.get_template("conditionals.txt")
>>> tpl.render(order_amount=51)
'No shipping costs.'
Congratulations, that was your very first Jinja conditional!
Now, you might also want to inform your users that shipping costs do apply when the amount is lower than €50
, in which case you could write:
{%- if order_amount < 50 -%}
Shipping costs apply.
{%- else -%}
No shipping costs.
{%- endif -%}
The {% else %}
statement is optional and will be used whenever the previous condition(s) do not apply. There can be at most one else
statement in each if
block.
Your e-commerce business is steadily growing, so you now want to charge different shipping costs according to the order's total amount:
€5
if the amount is lower than€10
€3
if the amount is lower than€25
€1
if the amount is lower than€50
€0
if the amount is greater or equal to€50
{%- if order_amount < 10 -%}
Shipping costs: 5€
{%- elif order_amount < 25 -%}
Shipping costs: €3
{%- elif order_amount < 50 -%}
Shipping costs: €1
{%- else -%}
Shipping costs: €0
{%- endif -%}
As you can see in the above example, you can use as many elif
statements as you need, but at most one else
branch.
Note: conditionals must always end with an endif
statement.
Comparison operators
You can compare variables or values using comparison operators:
==
: equal to!=
: not equal to>
: greater than<
: less than>=
: greater than or equal to<=
: less than or equal to
Logical operators
You can combine several comparisons into one using logical operators:
and
: returnsTrue
if both comparison expressions areTrue
or
: returnsTrue
if at least one comparison expression isTrue
not
: returnsTrue
if the comparison expression isFalse
(and viceversa)
Each of the following examples will meet the if
conditions and print the expected text:
# note: declared here to keep the example concise
{% set order_amount=5 %}
{% if order_amount >=0 and order_amount < 10 %}
Shipping costs: 5€
{% endif %}
# note: declared here to keep the example concise
{% set order_amount=10 %}
{% set user_has_discount=True %}
{% if order_amount >= 50 or user_has_discount %}
No shipping costs.
{% endif %}
# note: declared here to keep the example concise
{% set enabled=False %}
{% if not enabled %}
Disabled.
{% endif %}
Truthiness
Certain values are considered truthy by Jinja, while others are considered falsy: when you use an expression in a conditional statement, its value is first evaluated and then treated as either True
or False
based on its truthiness.
The following values are considered falsy by Jinja:
False
None
0
(integer)0.0
(float)- empty strings (e.g.
''
) - empty lists (e.g.
[]
) - empty dictionaries (e.g.
{}
) - empty sets (e.g.
set()
)
All other values are considered truthy: this includes, for example, any non-empty string or non-zero number, as well as any non-empty data structure such as a list with at least one item.
Rendering the following template
{% set n=0 %}
{% set s='' %}
{% set l=['a'] %}
{% if n %}
n is truthy
{% elif s %}
s is truthy
{% elif l %}
l is truthy
{% else %}
none of them is truthy
{% endif %}
will result in
l is truthy
because it's the only variable that has a truthy value.
Tests
Tests in Jinja2 are used to evaluate variables and determine if they pass a certain condition. They return a boolean value of either True or False, based on the outcome of the test.
To use this feature, simply add the is
keyword followed by the test name after the variable.
{% if variable is test_name %}
# ...
{% endif %}
The most commonly used test is the defined
test, which checks if a specific variable is present and defined in the data that is currently available to the Jinja interpreter.
This is particularly useful in ensuring that your Jinja Query handles undefined variables properly and can prevent incomplete outputs from being generated.
{% if variable is defined %}
Variable is defined
{% else %}
Variable is undefined
{% endif %}
Another useful family of tests are those used to check the data type of a variable. Certain operations, such as comparing numbers or iterating over lists and dictionaries, require that variables are of the same data type.
These tests can help you catch type mismatches and prevent errors from being thrown by Jinja.
boolean
- check is variable is a booleaninteger
- check if variable is an integerfloat
- check if variable is a floatnumber
- check if variable is number, will return True for both integer and floatstring
- check if variable is a stringmapping
- check if variable is a mapping, i.e. dictionaryiterable
- check if variable can be iterated over, will match string, list, dict, etc.sequence
- check if variable is a sequence
An example :
{% if variable is iterable %}
{% for item in variable %}
{{ item }}
{% endfor %}
{% else %}
{{ variable }}
{% endif %}
The above test checks whether the defined variable is iterable, and if so, iterates over it returning all contained items.
Else, it simply returns the variable.
Note: the comparison operators that we have previously seen are nothing but aliases of some built-in tests. For example, the following two conditionals are equivalent:
# using the comparison operator
{% if x > 0 %}
x is positive
{% endif %}
# using the equivalent test
{% if x is gt 0 %}
x is positive
{% endif %}
The complete list of built-in tests is available here.