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