Filters

💡
Learn how Jinja filters let you perform basic transformations to variables before they are rendered in a template. This is the fifth article in our series on Jinja templating.

You can add a filter to a variable using a pipe (|) character followed by the filter name and any arguments, if required. For example:


{{ "hello world" | title }}

# result
"Hello World"

will apply the filter title to "hello world", producing "Hello World" (note that the first letter of each word is now uppercase).

Multiple filters can be chained together in a single expression, as in the following example:


{{ ["hello", "world"] | join(" ") | title }}

# result
"Hello World"

will join the values into a single string separated by a whitespace, then apply title to the resulting string, producing the same result as in the previous snippet.

There are many built-in filters provided by Jinja and it's also possible to create custom filters.

Filter categories

Built-in filters can be categorized based on their functionality:

  • String filters: these include the capitalize,  lower,  upper,  title,  trim, striptags, and escape filters. These filters are useful for formatting text for display purposes.
  • List filters: these include the join,  first,  last,  length,  reverse, sort, map,  select, and reject filters. These filters are useful for manipulating list data.
  • Numeric filters: these include the abs, float, int, round, and random filters. These filters are useful for performing mathematical operations.
  • Miscellaneous filters: these include the default,  batch filters. These filters are used for a variety of purposes such as providing default values and splitting lists into smaller lists.

Let's have a look at some examples from each category.

String filters

escape

The escape filter  replaces those characters in the string that belong to the HTML syntax (&, <, >, ', and ") with HTML-safe sequences.


{{ "42 > 12" | escape }}

# result
"42 > 12"

format

The format filter lets you define a printf-style format string.


{% set text = "The answer is" %}
{% set num = 42 %}

{{ "%s %d" | format(text, num) }}

# result
"The answer is 42"

replace

The replace filter replaces the old string with the new one.


{{ "hello world" | replace(old="world", new="Jinja" }}

# result
hello Jinja

truncate

The truncate filter truncates the string at the specified length (including the 3 characters of the ellipsis). By default, it discards the last word instead of truncating at the exact length, but this can be changed.


{{ "Lorem ipsum dolor sit amet, consectetur adipiscing elit." | truncate(20) }}

# result
"Lorem ipsum..."

{{ "Lorem ipsum dolor sit amet, consectetur adipiscing elit." | truncate(20, killwords=True) }}

# result
"Lorem ipsum dolor..."

upper

Upper converts all letters in the string to upper case.


{{ "hello world" | upper }}

# result
"HELLO WORLD"

Iterable filters

groupby

The groupby filter lets you group items in a collection according to one of their attributes.


{% set users = [{'name': 'Sofia', 'city': 'Berlin'}, {'name': 'Mark', 'city': 'Berlin'}, {'name': 'Wouter', 'city': 'Hamburg'}] %}

{% for city, items in users | groupby('city') %}
	{{ city }}
	{% for user in items %}
		{{ user.name }}
	{% endfor %}
{% endfor %}

# result
Berlin
	Sofia
	Mark

Hamburg
	Wouter

map

The map filter lets you transform the values in a list, for example extracting a single attribute as in the following snippet


{% set users = [{'name': 'Sofia', 'city': 'Berlin'}, {'name': 'Mark', 'city': 'Berlin'}, {'name': 'Wouter', 'city': 'Hamburg'}] %}

{% for name in users | map(attribute='name') %}
  {{ name }}
{% endfor %}

# result
Sofia
Mark
Wouter

You may also choose a default value that will be displayed if any element is missing the attribute.


{% set users = [{'name': 'Sofia', 'city': 'Berlin'}, {'name': 'Mark', 'city': 'Berlin'}, {'name': 'Wouter', 'city': 'Hamburg'}] %}

{% for age in users | map(attribute='age', default='N/A') %}
  {{ age }}
{% endfor %}

# result
N/A
N/A
37

select

Suppose you have a list of numbers and you want to filter them so that you only get the even ones:


{% set numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] %}

{% for num in numbers | select('even') %}
    {{ num }}
{% endfor %}

# result
[2, 4, 6, 8]

The second argument accepted by the select filter is the name of a test (optionally followed by its own arguments, as necessary): the above snippet will run the even test on each value and only accept numbers that are even.

reject

The reject filter behaves in the opposite way as select, rejecting any elements that satisfy the test.

sort

The sort filter sorts the collection elements.


{{ [1, 9, 5, 7, 3] | sort }}

# result
[1, 3, 5, 7, 9]

You may also choose to sort elements in reverse order using sort(reverse=True).

If you are sorting a list of objects or dictionaries, you may choose which attribute(s) you'd like to sort by. For example:


{% set users = [{'name': 'Wendy', 'age': 29}, {'name': 'Katie', 'age': 45}] %}

{% users | sort(attribute='name') %}

# result
[{'name': 'Katie', 'age': 45}, {'name': 'Wendy', 'age': 29}]

{% users | sort(attribute='age') %}

# result
[{'name': 'Wendy', 'age': 29}, {'name': 'Katie', 'age': 45}]

unique

The unique filter return a list of unique elements from the given collection.


{{ [0, 1, 1, 2, 3, 5] | unique }}

# result
[0, 1, 2, 3, 5]

Numeric filters

abs

The abs filter returns the absolute value of its argument.


{{ -7 | abs }}

# result
7

int

The int filter converts a value into an integer value, if possible, returning a default value otherwise (0 by default).


{{ '42' | int }}

# result
42

You may change the default value that is returned when the conversion fails using the default=N argument, for example


{{ 'not a number' | int(default=-1) }}

# result
-1

You may also change the numeric base of the input string (set to 2 in the following snippet, to handle binary numbers).


{{ '0b101010' | int(base=2) }}

# result
42

The above snippet produces the integer value 42 (equivalent to the binary value 101010: 0b is a prefix required by Jinja to identify binary numbers).

Valid bases are:

  • 10: default, input string must represent a decimal number (e.g. 42)
  • 2: input string must start with 0b (e.g. 0b101010)
  • 8: input string must start with 0o (a zero followed by a lowercase o, e.g. 0o52)
  • 16: input string must start with 0x (e.g. 0x2A)

round

The round filter rounds a number to a given precision: by default this is 0, meaning that it will round to an integer value. The default rounding method rounds up or down to the nearest value with the desired precision. You can change this using the second argument, which accepts the following values:

  • common (default: round up or down)
  • ceil (always round up)
  • floor (always round down)

{{ 3.14159265359 | round }}

# result
3

# you can change the desired precision
{{ 3.14159265359 | round(precision=2) }}

# result
3.14

# or the rounding method
{{ 3.14159265359 | round(method='ceil') }}

# result
4

# or both
{{ 3.14159265359 | round(precision=2, method='ceil') }}

# result
3.15

Miscellaneous filters

default

Suppose you have a list of users, each with a set of attributes; all users have a name attribute, but some of them don't have an age attribute, so you'd like to be able to display some default value whenever the attribute is missing. This is where the default filter can help:


{% set users = [{'name': 'John', 'age': 21}, {'name': 'Andrea'}] %}

{% for user in users %}
	{{ user.name }}, {{ user.age | default('N/A') }}
{% endfor %}

# result
John, 21
Andrea, N/A