Extensions

The following sections cover the built-in Jinja2 extensions that may beenabled by an application. An application could also provide furtherextensions not covered by this documentation; in which case there shouldbe a separate document explaining said extensions.

i18n

If the i18n extension is enabled, it’s possible to mark parts in the templateas translatable. To mark a section as translatable, you can use trans:

  1. <p>{% trans %}Hello {{ user }}!{% endtrans %}</p>

To translate a template expression — say, using template filters, or by justaccessing an attribute of an object — you need to bind the expression to aname for use within the translation block:

  1. <p>{% trans user=user.username %}Hello {{ user }}!{% endtrans %}</p>

If you need to bind more than one expression inside a trans tag, separatethe pieces with a comma (,):

  1. {% trans book_title=book.title, author=author.name %}
  2. This is {{ book_title }} by {{ author }}
  3. {% endtrans %}

Inside trans tags no statements are allowed, only variable tags are.

To pluralize, specify both the singular and plural forms with the pluralize_tag, which appears between _trans and endtrans:

  1. {% trans count=list|length %}
  2. There is {{ count }} {{ name }} object.
  3. {% pluralize %}
  4. There are {{ count }} {{ name }} objects.
  5. {% endtrans %}

By default, the first variable in a block is used to determine the correctsingular or plural form. If that doesn’t work out, you can specify the namewhich should be used for pluralizing by adding it as parameter to pluralize:

  1. {% trans ..., user_count=users|length %}...
  2. {% pluralize user_count %}...{% endtrans %}

When translating longer blocks of text, whitespace and linebreaks result inrather ugly and error-prone translation strings. To avoid this, a trans blockcan be marked as trimmed which will replace all linebreaks and the whitespacesurrounding them with a single space and remove leading/trailing whitespace:

  1. {% trans trimmed book_title=book.title %}
  2. This is {{ book_title }}.
  3. You should read it!
  4. {% endtrans %}

If trimming is enabled globally, the notrimmed modifier can be used todisable it for a trans block.

New in version 2.10: The trimmed and notrimmed modifiers have been added.

It’s also possible to translate strings in expressions. For that purpose,three functions exist:

  • gettext: translate a single string

  • ngettext: translate a pluralizable string

  • __: alias for _gettext

For example, you can easily print a translated string like this:

  1. {{ _('Hello World!') }}

To use placeholders, use the format filter:

  1. {{ _('Hello %(user)s!')|format(user=user.username) }}

For multiple placeholders, always use keyword arguments to format,as other languages may not use the words in the same order.

Changelog

Changed in version 2.5.

If newstyle gettext calls are activated (Whitespace Trimming), usingplaceholders is a lot easier:

  1. {{ gettext('Hello World!') }}
  2. {{ gettext('Hello %(name)s!', name='World') }}
  3. {{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }}

Note that the ngettext function’s format string automatically receivesthe count as a num parameter in addition to the regular parameters.

Expression Statement

If the expression-statement extension is loaded, a tag called do is availablethat works exactly like the regular variable expression ({{ … }}); exceptit doesn’t print anything. This can be used to modify lists:

  1. {% do navigation.append('a string') %}

Loop Controls

If the application enables the Loop Controls, it’s possible touse break and continue in loops. When break is reached, the loop isterminated; if continue is reached, the processing is stopped and continueswith the next iteration.

Here’s a loop that skips every second item:

  1. {% for user in users %}
  2. {%- if loop.index is even %}{% continue %}{% endif %}
  3. ...
  4. {% endfor %}

Likewise, a loop that stops processing after the 10th iteration:

  1. {% for user in users %}
  2. {%- if loop.index >= 10 %}{% break %}{% endif %}
  3. {%- endfor %}

Note that loop.index starts with 1, and loop.index0 starts with 0(See: For).

With Statement

Changelog

New in version 2.3.

The with statement makes it possible to create a new inner scope.Variables set within this scope are not visible outside of the scope.

With in a nutshell:

  1. {% with %}
  2. {% set foo = 42 %}
  3. {{ foo }} foo is 42 here
  4. {% endwith %}
  5. foo is not visible here any longer

Because it is common to set variables at the beginning of the scope,you can do that within the with statement. The following two examplesare equivalent:

  1. {% with foo = 42 %}
  2. {{ foo }}
  3. {% endwith %}
  4. {% with %}
  5. {% set foo = 42 %}
  6. {{ foo }}
  7. {% endwith %}

An important note on scoping here. In Jinja versions before 2.9 thebehavior of referencing one variable to another had some unintendedconsequences. In particular one variable could refer to another definedin the same with block’s opening statement. This caused issues with thecleaned up scoping behavior and has since been improved. In particularin newer Jinja2 versions the following code always refers to the variablea from outside the with block:

  1. {% with a={}, b=a.attribute %}...{% endwith %}

In earlier Jinja versions the b attribute would refer to the results ofthe first attribute. If you depend on this behavior you can rewrite it touse the set tag:

  1. {% with a={} %}
  2. {% set b = a.attribute %}
  3. {% endwith %}

Extension

In older versions of Jinja (before 2.9) it was required to enable thisfeature with an extension. It’s now enabled by default.