Djangolike and Jinjalike template languages

A comparison between Django and Jinja “alike” template languages.

☕
3 min readMar 29, 2018

Restricting this article to the Python Community, there are two very similar categories of template languages: I call them Djangolike and Jinjalike.

Popular Djangolike template languages:

Popular Jinjalike template languages:

While the languages on the first group (Djangolike) are designed to look like markup, the languages on the second group (Jinjalike) look more like a programming language. We’ll see this later on…

All of them look like a mix of Python/Ruby and Bash. For instance, the vertical bar (|) is intended like a pipe (i.e. {{ value|upper }} ) and not like a bitwise operator.

Jinja2

Jinja2 is “modelled after Django’s templates” and the implementation share the same language (Python):

{% for row in rows %}
<li class="{{ loop.cycle('odd', 'even') }}">{{ row|upper }}</li>
{% endfor %}

It’s worth to notice that Jinja2 usually offers two ways of doing things:

  • Using a method {{ row.upper() }} ;
  • Using a pipe {{ row|upper }} .

Must be clear that Jinja2 methods are not actual Python. If you look for something even more similar to Python try Mako.

Django Template Language

While in Jinja2 arguments are inside parenthesis (like methods) in Django Template Language (DTL) arguments are introduced by a colon:

{{ username|default:'guest' }}

In DTL there is one obvious way to do it:

{% for row in rows %}
<li class="{% cycle 'odd' 'even' %}">{{ row|upper }}</li>
{% endfor %}

DTL is a delightful template language, even if it hasn’t a name on its own!

Liquid

Liquid was developed by Shopify co-founder and CEO Tobias Lütke.

It uses the same approach of Django Template Language however Liquid is a template language with a Ruby engine therefore the Liquid API mostly relies on Ruby.

Like in DTL, you can pass arguments after a colon:

{{ 'world!' | prepend: 'Hello, ' }}

However, in Liquid you have to use a comma between two arguments while in DTL you don’t need it:

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

Nunjucks

This popular template engine is “heavily inspired by Jinja2” which means that, even if it is a JavaScript implementation, you’ll be forced to use Python syntax (e.g. and instead of &&):

{% if firstname and lastname %}
<span>Hello, {{ firstname }} {{ lastname }}</span>
{% elif nickname %}
<span>Hello, {{ nickname }}!</span>
{% else %}
<span>Hello, guest!</span>
{% endif %}

However, Nunjucks is not a faithful Jinja2 implementation:

{% set c = cycler('odd', 'even') %}{% for row in rows %}
<li class="{{ c.next() }}">{{ row | upper }}</li>
{% endfor %}

Twig

Twig was originally written by Armin Ronacher (author of Jinja2) and extended by Fabien Potencier.

Twig is a PHP implementation that sometime does things in a Ruby fashion (e.g. range literals):

{% for year in 0..8 %}
<span>{{ cycle(['odd', 'even'], loop.index0) }}</span>
{% endfor %}

Sometime does things in a Python fashion (e.g. upper instead of upcase):

{% set c = ['odd', 'even'] %}

{% for row in rows %}
<li class="{{ cycle(c, loop.index0) }}">{{ row|upper }}</li>
{% endfor %}

Conclusion

A template language does not have to look like a general purpose programming language since it is designed for a different goal. For this reason my favorite template languages are Django TL, Hugo TL and Liquid: They are widely supported by text editors and have a consistent implementation.

DTL is one of the oldest and still one of the most effective template languages. With no surprise it’s a source of inspiration.

Anyway, if you don’t like template languages you can always try something like HyperScript?

--

--

☕
☕

Written by

#architect, #gis analyst, #computational designer, #tennis player, curious... somewhere between art and science.

No responses yet