Conditionals

💡
Learn how to use conditional statements in Jinja. This is the third article in our series on Jinja templating.

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: returns True if both comparison expressions are True
  • or: returns True if at least one comparison expression is True
  • not: returns True if the comparison expression is False (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 boolean
integer - check if variable is an integer
float - check if variable is a float
number - check if variable is number, will return True for both integer and float
string - check if variable is a string
mapping - check if variable is a mapping, i.e. dictionary
iterable - 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.


Next up:
Loops
Jump to

Start sending data-driven messages today

Sign up and start using PushMetrics for free.
Or schedule a demo and discuss your use case.