• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Switching from other Template Engines
2=====================================
3
4.. highlight:: html+jinja
5
6If you have used a different template engine in the past and want to switch
7to Jinja here is a small guide that shows the basic syntactic and semantic
8changes between some common, similar text template engines for Python.
9
10Jinja 1
11-------
12
13Jinja 2 is mostly compatible with Jinja 1 in terms of API usage and template
14syntax.  The differences between Jinja 1 and 2 are explained in the following
15list.
16
17API
18~~~
19
20Loaders
21    Jinja 2 uses a different loader API.  Because the internal representation
22    of templates changed there is no longer support for external caching
23    systems such as memcached.  The memory consumed by templates is comparable
24    with regular Python modules now and external caching doesn't give any
25    advantage.  If you have used a custom loader in the past have a look at
26    the new :ref:`loader API <loaders>`.
27
28Loading templates from strings
29    In the past it was possible to generate templates from a string with the
30    default environment configuration by using `jinja.from_string`.  Jinja 2
31    provides a :class:`Template` class that can be used to do the same, but
32    with optional additional configuration.
33
34Automatic unicode conversion
35    Jinja 1 performed automatic conversion of bytes in a given encoding
36    into unicode objects. This conversion is no longer implemented as it
37    was inconsistent as most libraries are using the regular Python
38    ASCII bytes to Unicode conversion. An application powered by Jinja 2
39    *has to* use unicode internally everywhere or make sure that Jinja 2
40    only gets unicode strings passed.
41
42i18n
43    Jinja 1 used custom translators for internationalization.  i18n is now
44    available as Jinja 2 extension and uses a simpler, more gettext friendly
45    interface and has support for babel.  For more details see
46    :ref:`i18n-extension`.
47
48Internal methods
49    Jinja 1 exposed a few internal methods on the environment object such
50    as `call_function`, `get_attribute` and others.  While they were marked
51    as being an internal method it was possible to override them.  Jinja 2
52    doesn't have equivalent methods.
53
54Sandbox
55    Jinja 1 was running sandbox mode by default.  Few applications actually
56    used that feature so it became optional in Jinja 2.  For more details
57    about the sandboxed execution see :class:`SandboxedEnvironment`.
58
59Context
60    Jinja 1 had a stacked context as storage for variables passed to the
61    environment.  In Jinja 2 a similar object exists but it doesn't allow
62    modifications nor is it a singleton.  As inheritance is dynamic now
63    multiple context objects may exist during template evaluation.
64
65Filters and Tests
66    Filters and tests are regular functions now.  It's no longer necessary
67    and allowed to use factory functions.
68
69
70Templates
71~~~~~~~~~
72
73Jinja 2 has mostly the same syntax as Jinja 1.  What's different is that
74macros require parentheses around the argument list now.
75
76Additionally Jinja 2 allows dynamic inheritance now and dynamic includes.
77The old helper function `rendertemplate` is gone now, `include` can be used
78instead.  Includes no longer import macros and variable assignments, for
79that the new `import` tag is used.  This concept is explained in the
80:ref:`import` documentation.
81
82Another small change happened in the `for`-tag.  The special loop variable
83doesn't have a `parent` attribute, instead you have to alias the loop
84yourself.  See :ref:`accessing-the-parent-loop` for more details.
85
86
87Django
88------
89
90If you have previously worked with Django templates, you should find
91Jinja very familiar.  In fact, most of the syntax elements look and
92work the same.
93
94However, Jinja provides some more syntax elements covered in the
95documentation and some work a bit different.
96
97This section covers the template changes.  As the API is fundamentally
98different we won't cover it here.
99
100Method Calls
101~~~~~~~~~~~~
102
103In Django method calls work implicitly, while Jinja requires the explicit
104Python syntax. Thus this Django code::
105
106    {% for page in user.get_created_pages %}
107        ...
108    {% endfor %}
109
110...looks like this in Jinja::
111
112    {% for page in user.get_created_pages() %}
113        ...
114    {% endfor %}
115
116This allows you to pass variables to the method, which is not possible in
117Django. This syntax is also used for macros.
118
119Filter Arguments
120~~~~~~~~~~~~~~~~
121
122Jinja provides more than one argument for filters.  Also the syntax for
123argument passing is different.  A template that looks like this in Django::
124
125    {{ items|join:", " }}
126
127looks like this in Jinja::
128
129    {{ items|join(', ') }}
130
131It is a bit more verbose, but it allows different types of arguments -
132including variables - and more than one of them.
133
134Tests
135~~~~~
136
137In addition to filters there also are tests you can perform using the is
138operator.  Here are some examples::
139
140    {% if user.user_id is odd %}
141        {{ user.username|e }} is odd
142    {% else %}
143        hmm. {{ user.username|e }} looks pretty normal
144    {% endif %}
145
146Loops
147~~~~~
148
149For loops work very similarly to Django, but notably the Jinja special
150variable for the loop context is called `loop`, not `forloop` as in Django.
151
152In addition, the Django `empty` argument is called `else` in Jinja. For
153example, the Django template::
154
155    {% for item in items %}
156        {{ item }}
157    {% empty %}
158        No items!
159    {% endfor %}
160
161...looks like this in Jinja::
162
163    {% for item in items %}
164        {{ item }}
165    {% else %}
166        No items!
167    {% endfor %}
168
169Cycle
170~~~~~
171
172The ``{% cycle %}`` tag does not exist in Jinja; however, you can achieve the
173same output by using the `cycle` method on the loop context special variable.
174
175The following Django template::
176
177    {% for user in users %}
178        <li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
179    {% endfor %}
180
181...looks like this in Jinja::
182
183    {% for user in users %}
184        <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
185    {% endfor %}
186
187There is no equivalent of ``{% cycle ... as variable %}``.
188
189
190Mako
191----
192
193.. highlight:: html+mako
194
195If you have used Mako so far and want to switch to Jinja you can configure
196Jinja to look more like Mako:
197
198.. sourcecode:: python
199
200    env = Environment('<%', '%>', '${', '}', '<%doc>', '</%doc>', '%', '##')
201
202With an environment configured like that, Jinja should be able to interpret
203a small subset of Mako templates.  Jinja does not support embedded Python
204code, so you would have to move that out of the template.  The syntax for defs
205(which are called macros in Jinja) and template inheritance is different too.
206The following Mako template::
207
208    <%inherit file="layout.html" />
209    <%def name="title()">Page Title</%def>
210    <ul>
211    % for item in list:
212        <li>${item}</li>
213    % endfor
214    </ul>
215
216Looks like this in Jinja with the above configuration::
217
218    <% extends "layout.html" %>
219    <% block title %>Page Title<% endblock %>
220    <% block body %>
221    <ul>
222    % for item in list:
223        <li>${item}</li>
224    % endfor
225    </ul>
226    <% endblock %>
227