aboutsummaryrefslogtreecommitdiff
path: root/docs/switching.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/switching.rst')
-rw-r--r--docs/switching.rst226
1 files changed, 226 insertions, 0 deletions
diff --git a/docs/switching.rst b/docs/switching.rst
new file mode 100644
index 00000000..b9ff954c
--- /dev/null
+++ b/docs/switching.rst
@@ -0,0 +1,226 @@
+Switching from other Template Engines
+=====================================
+
+.. highlight:: html+jinja
+
+If you have used a different template engine in the past and want to switch
+to Jinja here is a small guide that shows the basic syntactic and semantic
+changes between some common, similar text template engines for Python.
+
+Jinja 1
+-------
+
+Jinja 2 is mostly compatible with Jinja 1 in terms of API usage and template
+syntax. The differences between Jinja 1 and 2 are explained in the following
+list.
+
+API
+~~~
+
+Loaders
+ Jinja 2 uses a different loader API. Because the internal representation
+ of templates changed there is no longer support for external caching
+ systems such as memcached. The memory consumed by templates is comparable
+ with regular Python modules now and external caching doesn't give any
+ advantage. If you have used a custom loader in the past have a look at
+ the new :ref:`loader API <loaders>`.
+
+Loading templates from strings
+ In the past it was possible to generate templates from a string with the
+ default environment configuration by using `jinja.from_string`. Jinja 2
+ provides a :class:`Template` class that can be used to do the same, but
+ with optional additional configuration.
+
+Automatic unicode conversion
+ Jinja 1 performed automatic conversion of bytes in a given encoding
+ into unicode objects. This conversion is no longer implemented as it
+ was inconsistent as most libraries are using the regular Python
+ ASCII bytes to Unicode conversion. An application powered by Jinja 2
+ *has to* use unicode internally everywhere or make sure that Jinja 2
+ only gets unicode strings passed.
+
+i18n
+ Jinja 1 used custom translators for internationalization. i18n is now
+ available as Jinja 2 extension and uses a simpler, more gettext friendly
+ interface and has support for babel. For more details see
+ :ref:`i18n-extension`.
+
+Internal methods
+ Jinja 1 exposed a few internal methods on the environment object such
+ as `call_function`, `get_attribute` and others. While they were marked
+ as being an internal method it was possible to override them. Jinja 2
+ doesn't have equivalent methods.
+
+Sandbox
+ Jinja 1 was running sandbox mode by default. Few applications actually
+ used that feature so it became optional in Jinja 2. For more details
+ about the sandboxed execution see :class:`SandboxedEnvironment`.
+
+Context
+ Jinja 1 had a stacked context as storage for variables passed to the
+ environment. In Jinja 2 a similar object exists but it doesn't allow
+ modifications nor is it a singleton. As inheritance is dynamic now
+ multiple context objects may exist during template evaluation.
+
+Filters and Tests
+ Filters and tests are regular functions now. It's no longer necessary
+ and allowed to use factory functions.
+
+
+Templates
+~~~~~~~~~
+
+Jinja 2 has mostly the same syntax as Jinja 1. What's different is that
+macros require parentheses around the argument list now.
+
+Additionally Jinja 2 allows dynamic inheritance now and dynamic includes.
+The old helper function `rendertemplate` is gone now, `include` can be used
+instead. Includes no longer import macros and variable assignments, for
+that the new `import` tag is used. This concept is explained in the
+:ref:`import` documentation.
+
+Another small change happened in the `for`-tag. The special loop variable
+doesn't have a `parent` attribute, instead you have to alias the loop
+yourself. See :ref:`accessing-the-parent-loop` for more details.
+
+
+Django
+------
+
+If you have previously worked with Django templates, you should find
+Jinja very familiar. In fact, most of the syntax elements look and
+work the same.
+
+However, Jinja provides some more syntax elements covered in the
+documentation and some work a bit different.
+
+This section covers the template changes. As the API is fundamentally
+different we won't cover it here.
+
+Method Calls
+~~~~~~~~~~~~
+
+In Django method calls work implicitly, while Jinja requires the explicit
+Python syntax. Thus this Django code::
+
+ {% for page in user.get_created_pages %}
+ ...
+ {% endfor %}
+
+...looks like this in Jinja::
+
+ {% for page in user.get_created_pages() %}
+ ...
+ {% endfor %}
+
+This allows you to pass variables to the method, which is not possible in
+Django. This syntax is also used for macros.
+
+Filter Arguments
+~~~~~~~~~~~~~~~~
+
+Jinja provides more than one argument for filters. Also the syntax for
+argument passing is different. A template that looks like this in Django::
+
+ {{ items|join:", " }}
+
+looks like this in Jinja::
+
+ {{ items|join(', ') }}
+
+It is a bit more verbose, but it allows different types of arguments -
+including variables - and more than one of them.
+
+Tests
+~~~~~
+
+In addition to filters there also are tests you can perform using the is
+operator. Here are some examples::
+
+ {% if user.user_id is odd %}
+ {{ user.username|e }} is odd
+ {% else %}
+ hmm. {{ user.username|e }} looks pretty normal
+ {% endif %}
+
+Loops
+~~~~~
+
+For loops work very similarly to Django, but notably the Jinja special
+variable for the loop context is called `loop`, not `forloop` as in Django.
+
+In addition, the Django `empty` argument is called `else` in Jinja. For
+example, the Django template::
+
+ {% for item in items %}
+ {{ item }}
+ {% empty %}
+ No items!
+ {% endfor %}
+
+...looks like this in Jinja::
+
+ {% for item in items %}
+ {{ item }}
+ {% else %}
+ No items!
+ {% endfor %}
+
+Cycle
+~~~~~
+
+The ``{% cycle %}`` tag does not exist in Jinja; however, you can achieve the
+same output by using the `cycle` method on the loop context special variable.
+
+The following Django template::
+
+ {% for user in users %}
+ <li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
+ {% endfor %}
+
+...looks like this in Jinja::
+
+ {% for user in users %}
+ <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
+ {% endfor %}
+
+There is no equivalent of ``{% cycle ... as variable %}``.
+
+
+Mako
+----
+
+.. highlight:: html+mako
+
+If you have used Mako so far and want to switch to Jinja you can configure
+Jinja to look more like Mako:
+
+.. sourcecode:: python
+
+ env = Environment('<%', '%>', '${', '}', '<%doc>', '</%doc>', '%', '##')
+
+With an environment configured like that, Jinja should be able to interpret
+a small subset of Mako templates. Jinja does not support embedded Python
+code, so you would have to move that out of the template. The syntax for defs
+(which are called macros in Jinja) and template inheritance is different too.
+The following Mako template::
+
+ <%inherit file="layout.html" />
+ <%def name="title()">Page Title</%def>
+ <ul>
+ % for item in list:
+ <li>${item}</li>
+ % endfor
+ </ul>
+
+Looks like this in Jinja with the above configuration::
+
+ <% extends "layout.html" %>
+ <% block title %>Page Title<% endblock %>
+ <% block body %>
+ <ul>
+ % for item in list:
+ <li>${item}</li>
+ % endfor
+ </ul>
+ <% endblock %>