blob: 01a7d0d787bec234c40fe1f541db234ab1a50348 [file] [log] [blame]
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +02001Switching from other Template Engines
2=====================================
3
4.. highlight:: html+jinja
5
Sakti Dwi Cahyonoa29f9dd2013-02-15 14:08:45 +07006If you have used a different template engine in the past and want to switch
Alex Chan972c0302015-04-05 22:42:34 +01007to Jinja2 here is a small guide that shows the basic syntactic and semantic
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +02008changes between some common, similar text template engines for Python.
9
10Jinja1
11------
12
13Jinja2 is mostly compatible with Jinja1 in terms of API usage and template
14syntax. The differences between Jinja1 and 2 are explained in the following
15list.
16
17API
18~~~
19
20Loaders
21 Jinja2 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`. Jinja2
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 Jinja1 performed automatic conversion of bytestrings 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 ASCII
38 bytestring to Unicode conversion. An application powered by Jinja2
39 *has to* use unicode internally everywhere or make sure that Jinja2 only
40 gets unicode strings passed.
41
42i18n
43 Jinja1 used custom translators for internationalization. i18n is now
44 available as Jinja2 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 Jinja1 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. Jinja2
52 doesn't have equivalent methods.
53
54Sandbox
55 Jinja1 was running sandbox mode by default. Few applications actually
56 used that feature so it became optional in Jinja2. For more details
57 about the sandboxed execution see :class:`SandboxedEnvironment`.
58
59Context
60 Jinja1 had a stacked context as storage for variables passed to the
61 environment. In Jinja2 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
Armin Ronacher09c002e2008-05-10 22:21:30 +020065Filters and Tests
66 Filters and tests are regular functions now. It's no longer necessary
67 and allowed to use factory functions.
68
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020069
70Templates
71~~~~~~~~~
72
Armin Ronacher2b228742008-05-18 20:29:32 +020073Jinja2 has mostly the same syntax as Jinja1. What's different is that
74macros require parentheses around the argument list now.
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020075
Armin Ronacher2b228742008-05-18 20:29:32 +020076Additionally Jinja2 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
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020079that the new `import` tag is used. This concept is explained in the
80:ref:`import` documentation.
81
Armin Ronachere2244882008-05-19 09:25:57 +020082Another 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
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020086
87Django
88------
89
90If you have previously worked with Django templates, you should find
91Jinja2 very familiar. In fact, most of the syntax elements look and
92work the same.
93
94However, Jinja2 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
Markus Unterwaditzerf1668bd2015-03-11 21:26:24 +0100103In Django method calls work implicitly, while Jinja requires the explicit
104Python syntax. Thus this Django code::
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200105
106 {% for page in user.get_created_pages %}
107 ...
108 {% endfor %}
Adam Chainz382ee702014-07-12 23:03:55 +0100109
110...looks like this in Jinja::
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200111
112 {% for page in user.get_created_pages() %}
113 ...
114 {% endfor %}
115
Adam Chainz382ee702014-07-12 23:03:55 +0100116This allows you to pass variables to the method, which is not possible in
117Django. This syntax is also used for macros.
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200118
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200119Filter Arguments
120~~~~~~~~~~~~~~~~
121
122Jinja2 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 Jinja2::
128
129 {{ items|join(', ') }}
130
Adam Chainz382ee702014-07-12 23:03:55 +0100131It is a bit more verbose, but it allows different types of arguments -
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200132including 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
Armin Ronacher9bb7e472008-05-28 11:26:59 +0200146Loops
147~~~~~
148
Adam Chainz382ee702014-07-12 23:03:55 +0100149For loops work very similarly to Django, but notably the Jinja2 special
150variable for the loop context is called `loop`, not `forloop` as in Django.
Ned Jackson Lovely7336b7a2012-03-12 20:45:08 -0400151
Adam Chainz382ee702014-07-12 23:03:55 +0100152In addition, the Django `empty` argument is called `else` in Jinja2. For
153example, the Django template::
Ned Jackson Lovely7336b7a2012-03-12 20:45:08 -0400154
155 {% for item in items %}
Armin Ronacher4b2c9262013-05-19 11:36:52 +0100156 {{ item }}
Ned Jackson Lovely7336b7a2012-03-12 20:45:08 -0400157 {% empty %}
158 No items!
159 {% endfor %}
160
Adam Chainz382ee702014-07-12 23:03:55 +0100161...looks like this in Jinja2::
Ned Jackson Lovely7336b7a2012-03-12 20:45:08 -0400162
163 {% for item in items %}
Armin Ronacher4b2c9262013-05-19 11:36:52 +0100164 {{ item }}
Ned Jackson Lovely7336b7a2012-03-12 20:45:08 -0400165 {% else %}
166 No items!
167 {% endfor %}
Armin Ronacher9bb7e472008-05-28 11:26:59 +0200168
Armin Ronacherf288b7a2008-06-19 09:41:56 +0200169Cycle
170~~~~~
171
Adam Chainz382ee702014-07-12 23:03:55 +0100172The ``{% cycle %}`` tag does not exist in Jinja2; however, you can achieve the
173same output by using the `cycle` method on the loop context special variable.
Armin Ronacherf288b7a2008-06-19 09:41:56 +0200174
175The following Django template::
176
177 {% for user in users %}
178 <li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
179 {% endfor %}
180
Adam Chainz382ee702014-07-12 23:03:55 +0100181...looks like this in Jinja2::
Armin Ronacherf288b7a2008-06-19 09:41:56 +0200182
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
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200189
190Mako
191----
192
193.. highlight:: html+mako
194
195If you have used Mako so far and want to switch to Jinja2 you can configure
196Jinja2 to look more like Mako:
197
198.. sourcecode:: python
199
Florent Xiclunae04e32f2012-02-05 12:14:08 +0100200 env = Environment('<%', '%>', '${', '}', '<%doc>', '</%doc>', '%', '##')
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200201
Adam Chainz382ee702014-07-12 23:03:55 +0100202With an environment configured like that, Jinja2 should be able to interpret
203a small subset of Mako templates. Jinja2 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 Jinja2) and template inheritance is different too.
206The following Mako template::
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200207
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 Jinja2 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 %>