blob: 3de07d110eda58389d1ba4248e369d8f318da4c8 [file] [log] [blame]
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +02001Switching 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 swtich
7to Jinja2 here is a small guide that shows the basic syntatic and semantic
8changes 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
65
66Templates
67~~~~~~~~~
68
69Jinja2 has mostly the same syntax as Jinja1. The only difference is that
70assigning variables doesn't use `set` as keyword now. The following
71example shows a Jinja1 variable assignment::
72
73 {% set foo = 42 %}
74
75In Jinja2 the `set` is ommited::
76
77 {% foo = 42 %}
78
79Additionally macros require parentheses around the argument list now.
80
81Jinja2 allows dynamic inheritance now and dynamic includes. The old helper
82function `rendertemplate` is gone now, `include` can be used instead.
83Additionally includes no longer import macros and variable assignments, for
84that the new `import` tag is used. This concept is explained in the
85:ref:`import` documentation.
86
87Currently there is no support for the `recursive` modifier of for loops!
88
89
90Django
91------
92
93If you have previously worked with Django templates, you should find
94Jinja2 very familiar. In fact, most of the syntax elements look and
95work the same.
96
97However, Jinja2 provides some more syntax elements covered in the
98documentation and some work a bit different.
99
100This section covers the template changes. As the API is fundamentally
101different we won't cover it here.
102
103Method Calls
104~~~~~~~~~~~~
105
106In Django method calls work implicitly. With Jinja2 you have to specify that
107you want to call an object. Thus this Django code::
108
109 {% for page in user.get_created_pages %}
110 ...
111 {% endfor %}
112
113will look like this in Jinja::
114
115 {% for page in user.get_created_pages() %}
116 ...
117 {% endfor %}
118
119This allows you to pass variables to the function which is also used for macros
120which is not possible in Django.
121
122Conditions
123~~~~~~~~~~
124
125In Django you can use the following constructs to check for equality::
126
Georg Brandl3863b652008-05-11 12:56:50 +0200127 {% ifequal foo "bar" %}
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200128 ...
129 {% else %}
130 ...
Georg Brandl3863b652008-05-11 12:56:50 +0200131 {% endifequal %}
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +0200132
133In Jinja2 you can use the normal if statement in combination with operators::
134
135 {% if foo == 'bar' %}
136 ...
137 {% else %}
138 ...
139 {% endif %}
140
141You can also have multiple elif branches in your template::
142
143 {% if something %}
144 ...
145 {% elif otherthing %}
146 ...
147 {% elif foothing %}
148 ...
149 {% else %}
150 ...
151 {% endif %}
152
153Filter Arguments
154~~~~~~~~~~~~~~~~
155
156Jinja2 provides more than one argument for filters. Also the syntax for
157argument passing is different. A template that looks like this in Django::
158
159 {{ items|join:", " }}
160
161looks like this in Jinja2::
162
163 {{ items|join(', ') }}
164
165In fact it's a bit more verbose but it allows different types of arguments -
166including variables - and more than one of them.
167
168Tests
169~~~~~
170
171In addition to filters there also are tests you can perform using the is
172operator. Here are some examples::
173
174 {% if user.user_id is odd %}
175 {{ user.username|e }} is odd
176 {% else %}
177 hmm. {{ user.username|e }} looks pretty normal
178 {% endif %}
179
180
181Mako
182----
183
184.. highlight:: html+mako
185
186If you have used Mako so far and want to switch to Jinja2 you can configure
187Jinja2 to look more like Mako:
188
189.. sourcecode:: python
190
191 env = Environment('<%', '%>', '${', '}', '%')
192
193Once the environment is configure like that Jinja2 should be able to interpret
194a small subset of Mako templates. Jinja2 does not support embedded Python code
195so you would have to move that out of the template. The syntax for defs (in
196Jinja2 defs are called macros) and template inheritance is different too. The
197following Mako template::
198
199 <%inherit file="layout.html" />
200 <%def name="title()">Page Title</%def>
201 <ul>
202 % for item in list:
203 <li>${item}</li>
204 % endfor
205 </ul>
206
207Looks like this in Jinja2 with the above configuration::
208
209 <% extends "layout.html" %>
210 <% block title %>Page Title<% endblock %>
211 <% block body %>
212 <ul>
213 % for item in list:
214 <li>${item}</li>
215 % endfor
216 </ul>
217 <% endblock %>