Jinja built-in filters and tests (like Django filters)

The Jinja documentation makes an explicit difference between what it calls filters and tests. The only difference is Jinja tests are used to evaluate conditions and Jinja filters are used to format or transform values. In Django there is no such naming difference and an equivalent Jinja test in Django is simply called a Django filter.

The syntax to apply Jinja filters to template variables is the vertical bar character | , also called a 'pipe' in Unix environments (e.g.{{variable|filter}}). It's worth mentioning you can apply multiple filters to the same variable (e.g.{{variable|filter|filter}}). The syntax to apply Jinja tests uses the is keyword along with a regular conditional to evaluate the validity of a test (e.g. {% if variable is divisibleby 10 %}do something{% endif %}).

In the upcoming sections, I'll add the reference (Test) to indicate it's referring to a Jinja test vs. a Jinja filter. I'll also classify each Django built-in filter & test into functional sections so they are easier to identify. I'll define the broadest category 'Strings, lists, dictionaries, numbers and objects' for filters and tests that pplicable for most scenarios and then more specialized sections for each data type, including: 'String and lists', 'Dictionaries and objects', Strings, Numbers, Spacing and special characters, Development and testing and Urls.

Strings, lists, dictionaries, numbers and objects

Listing 4-19 Jinja defined test

{% if variable is defined %}
    value of variable: {{ variable }}
{% else %}
    variable is not defined
{% endif %}

Strings and lists

Dictionaries and objects

Listing 4-20. Jinja groupby filter

# Dictionary definition
stores = [
    {'name': 'Downtown', 'street': '385 Main Street', 'city': 'San Diego'},
    {'name': 'Uptown', 'street': '231 Highland Avenue', 'city': 'San Diego'},
    {'name': 'Midtown', 'street': '85 Balboa Street', 'city': 'San Diego'},
    {'name': 'Downtown', 'street': '639 Spring Street', 'city': 'Los Angeles'},
    {'name': 'Midtown', 'street': '1407 Broadway Street', 'city': 'Los Angeles'},
    {'name': 'Downton', 'street': '50 1st Street', 'city': 'San Francisco'},
]

<ul>
{% for group in stores|groupby('city') %}
    <li>{{ group.grouper }}
    <ul>
        {% for item in group.list %}
          <li>{{ item.name }}: {{ item.street }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

# Output
Los Angeles
    Downtown: 639 Spring Street
    Midtown: 1407 Broadway Street
San Diego
    Downtown : 385 Main Street
    Uptown : 231 Highland Avenue
    Midtown : 85 Balboa Street
San Francisco
    Downtown: 50 1st Street

# Alternate shortcut syntax, produces same output
<ul>
{% for grouper, list in stores|groupby('city') %}
    <li>{{ grouper }}
    <ul>
        {% for item in list %}
          <li>{{ item.name }}: {{ item.street }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>
Tip You can globally set options for the tojson filter through Jinja policies, described in the last section of this chapter.

Strings

Numbers

Spacing and special characters

Tip You can globally set the leeway value for the truncate filter through Jinja policies, described in the last section of this chapter.

Listing 4-21. Jinja wordwrap filter

# Variable definition 
Coffeehouse started as a small store

# Template definition with wordwrap filter for every 12 characters
{{variable|wordwrap(12)}}

# Output
Coffeehouse 
started as a
small store

Listing 4-22. Django xmlattr filter

# Variable definition 
{% set stores = [
    {'id':123,'name': 'Downtown', 'street': '385 Main Street', 'city': 'San Diego'},
    {'id':243,'name': 'Uptown', 'street': '231 Highland Avenue', 'city': 'San Diego'},
    {'id':357,'name': 'Midtown', 'street': '85 Balboa Street', 'city': 'San Diego'},
    {'id':478,'name': 'Downtown', 'street': '639 Spring Street', 'city': 'Los Angeles'},
    {'id':529,'name': 'Midtown', 'street': '1407 Broadway Street', 'city': 'Los Angeles'},
    {'id':653,'name': 'Downton', 'street': '50 1st Street', 'city': 'San Francisco'},
] %}

# Template definition
<ul>
{% for store in stores %}
  <li {{ {'id':'%d'|format(store.id),'class':'%s'|format(store.city|lower|replace(' ','-')) }|xmlattr }}>
               {{store.city}} {{store.name}}
  </li>
{% endfor %}
</ul>

# Output
<ul>
  <li id="123" class="san-diego"> San Diego Downtown</li>
  <li id="243" class="san-diego"> San Diego Uptown</li>
  <li id="357" class="san-diego"> San Diego Midtown</li>
  <li id="478" class="los-angeles"> Los Angeles Downtown</li>
  <li id="529" class="los-angeles"> Los Angeles Midtown</li>
  <li id="653" class="san-francisco"> San Francisco Downton</li>
</ul>

Development and testing

Urls

Tip You can globally set rel and target values for the the urlize filter through Jinja policies, described in the last section of this chapter.