Jinja

Recipies

Navigation

Contents

Here are some typical recipes for the usage of Jinja templates.

Alternating Rows

If you want to have different styles for each row of a table or list you can use the cycle tag:

<ul>
{% for row in sequence %}
  <li class="{% cycle 'even', 'odd' %}">{{ row|e }}</li>
{% endfor %}
</ul>

cycle can take an unlimited amount of strings. Each time this tag is encountered the next item from the list is rendered. If you pass it just one argument it's meant to be a sequence.

Active Menu Item

Often you want to have a navigation bar with an active navigation item. This is really simple to achieve. Because set tags outside of blocks are global you can do something like this:

layout.html:

{% set navigation_bar = [
    ('/', 'index', 'Index'),
    ('/downloads/', 'downloads', 'Downloads'),
    ('/about/', 'about', 'About')
] %}
...
<ul id="navigation">
{% for href, id, caption in navigation_bar %}
  <li{% if id == active_page %} class="active"{% endif
  %}><a href="{{ href|e }}">{{ caption|e }}</a>/li>
{% endfor %}
</ul>
...

index.html:

{% extends "layout.html" %}
{% set active_page = "index" %}

Sitemap

To create a sitemap you can either use the for tag or a macro that calls itself. The datastructures should look like this:

{'sitemap': [
    dict(
        caption='Pages',
        children=[
            dict(href='index.html', caption='Index'),
            dict(href='downloads.html', caption='Downloads'),
            dict(
                caption='Users',
                children=[
                    dict(href='peter.html',
                         caption='Peter'),
                    dict(href='max.html',
                         caption='Max'),
                    dict(href='suzan.html',
                         caption='Suzan')
                ]
            ),
            dict(
                caption='Files',
                children=[
                    dict(
                        caption='Images',
                        children=[
                            dict(href='vienna.html',
                                 caption='Vienna'),
                            dict(href='roma.html',
                                 caption='Roma'),
                            dict(href='tokyo.html',
                                 caption='Tokyo')
                        ]
                    ),
                    dict(
                        caption='Videos',
                        children=[
                            dict(href='party.html',
                                 caption='Party')
                        ]
                    )
                ]
            )
        ]
    ),
    dict(caption='Foo', href='foo.html')
    dict(caption='About', href='about.html')
]}

Now you can create a sitemap using for:

<ul class="sitemap">
{% for item in sitemap recursive %}
  <li><a href="{{ item.href|e }}">{{ item.caption|e }}</a>
  {% if item.children %}<ul>{{ loop(item.children) }}</ul>{% endif %}</li>
{% endfor %}
</ul>

Or by using a macro that calls itself:

{% macro render_sitemap items %}
  {% for item in items %}
    <li><a href="{{ item.href|e }}">{{ item.caption|e }}</a>
    {% if item.children %}<ul>{{ render_sitemap(item.children) }}</ul>{% endif %}</li>
  {% endfor %}
{% endmacro %}
<ul class="sitemap">{{ render_sitemap(sitemap) }}</ul>

Using A Block Multiple Times

Blocks have the small disadvantage that they work both ways which is a problem if you want to render a block two times on a page. Here a nice little workaround for this limitation:

<html>
  <head>
    <title>{% filter capture('title') %}{%
              block title %}{% endblock %}{%
              endfilter %}</title>
  </head>
  <body>
    <div class="head">{{ title }}</div>
  </body>
</html>

Or if you use the capture filter in clean mode:

{% filter capture('title', True)|trim %}
  {% block title %}{% endblock %}
{% endfilter %}
<html>
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    <div class="head">{{ title }}</div>
  </body>
</html>

Vim Syntax Highlighting

Because of the similar syntax to django you can use the django highlighting plugin for jinja too. There is however a Jinja syntax highlighting plugin too which supports all of the syntax elements.

You can download it from the vim webpage: jinja.vim