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 %}