Select Page

Introduction

Jinja is a modern templating language for Python.

It enables dynamic expressions, filters, and access to variables, by providing Python-like expressions. It is used to generate any markup or source code.

Official Documentation: https://jinja.palletsprojects.com/en/3.1.x/

Basic Concepts

Statements {% ... %} – primarily control statements

Expressions {{ ... }} – prints as a template output

Comments {# … ##} – to prevent something from being included in the template output

Variables

Access variables within the Jinja template same as we do in Python.

{{ somevar }}

{{ someovar.attribute }}

{{ somevar['attribute'] }}

{{ somevar.get('attribute') }}

Set custom variables within the Jinja template.

{% set somebool = true %}

Data Types

Type Description
Boolean Represents the values true and false.
Integer Whole numbers without a decimal part.
Floating point Numbers with a decimal point ‘.’
Sequence List of items enclosed with square brackets, same as [‘a’]
String A sequence of characters, either as a literal constant or as some kind of variable
Tuple Can contain two values of different data types
Mappings {'dict': 'of', 'key': 'and', 'value': 'pairs'}

Logic Conditions

if-elif-else-endif

{% if condition %}
  {{ do this }}
{% elif condition %}
  {{ do this instead }}
{% else %}
  {{ do this when no condition met }}
{% endif %}

for-endfor

{% for item in sequence %}
  {{ item }}
{% endfor %}

loop helpers

{% for item in sequence %}
  {{ loop.first }}
  {{ loop.last }}
  {{ loop.index }}
  {{ loop.index0 }}
  {{ loop.lenght }}
  {{ loop.cycle('odd', 'even') }} - {{ item }}
  {{ loop.revindex }}
  {{ loop.revindex0 }}
  {{ loop.depth }}
  {{ loop.depth0 }}
  {{ loop.previtem }}
  {{ loop.nextitem }}
  {{ loop.changed(*val) }}
{% endfor %}

Filters

Two forms: Inline (using | operator) and block filters (using {% filter <filter_name> %} block {% endfilter %} form)

List of builtin filters:

abs
attr
batch
capitalize
center
default
dictsort
escape
filesizeformat
first
float
forceescape
format
groupby
indent
int
items
join
last
length
list
lower
map
max
min
pprint
random
reject
rejectattr
replace
reverse
round
safe
select
selectattr
slice
sort
string
striptags
sum
title
tojson
trim
truncate
unique
upper
urlencode
urlize
wordcount
wordwrap
xmlattr

Tests

boolean
callable
defined
divisibleby
eq
escaped
even
false
filter
float
ge
gt
in
integer
iterable
le
lower
lt
mapping
ne
none
number
odd
sameas
sequence
string
test
true
undefined
upper

Escape

Two modes: Manual and automatic escape

For manual escape, none of the HTML is escaped. Escape a variable using |e filter. If a variable includes HTML-sensitive chars <, >, >, “ should be escaped properly.

For automatic escape, all of the HTML is escaped automatically. To prevent HTML from escaping use filter safe inline or in block mode.

Macros (aka functions/methods)

Keep Jinja templates DRY.

{% macro input(name, value='', type='text') -%}
  <input name=""{{ name }}"" type=""{{ type }}"" value=""{{ value|e }}"">
{%- endmacro %}

Call the macro like a function:

<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>

Macro’s special variables:

varargs kwargs caller

Macro’s special objects:

name arguments catch_varargs catch_kwargs

Note: To prevent the macro from being imported, name it prefixed with an underscore.

A macro in a child template does not override a macro in a parent template — due to how scopes work in Jinja.

Call a macro from a macro using call block. Standard example from Jinja doc.

{% macro render_dialog(title, class='dialog') -%}
<div class=""{{ class }}"">
  <h2>{{ title }}</h2>
  <div class=""contents"">{{ caller() }}</div>
</div>
{%- endmacro %} {% call render_dialog('Hello World') %} This is a simple dialog
rendered by using a macro and a call block. {% endcall %}

call block with arguments.

{% macro dump_users(users) -%}
<ul>
    {%- for user in users %}   
  <li>
        
    <p>{{ user.username|e }}</p>
        {{ caller(user) }}   
  </li>
    {%- endfor %}
</ul>
{%- endmacro %} {% call(user) dump_users(list_of_user) %}
<dl>
    
  <dt>Realname</dt>
    
  <dd>{{ user.realname|e }}</dd>
    
  <dt>Description</dt>
    
  <dd>{{ user.description }}</dd>
</dl>
{% endcall %}