You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.9 KiB
176 lines
6.9 KiB
Frequently Asked Questions
|
|
==========================
|
|
|
|
This page answers some of the often asked questions about Jinja.
|
|
|
|
.. highlight:: html+jinja
|
|
|
|
Why is it called Jinja?
|
|
-----------------------
|
|
|
|
The name Jinja was chosen because it's the name of a Japanese temple and
|
|
temple and template share a similar pronunciation. It is not named after
|
|
the city in Uganda.
|
|
|
|
How fast is it?
|
|
---------------
|
|
|
|
We really hate benchmarks especially since they don't reflect much. The
|
|
performance of a template depends on many factors and you would have to
|
|
benchmark different engines in different situations. The benchmarks from the
|
|
testsuite show that Jinja has a similar performance to `Mako`_ and is between
|
|
10 and 20 times faster than Django's template engine or Genshi. These numbers
|
|
should be taken with tons of salt as the benchmarks that took these numbers
|
|
only test a few performance related situations such as looping. Generally
|
|
speaking the performance of a template engine doesn't matter much as the
|
|
usual bottleneck in a web application is either the database or the application
|
|
code.
|
|
|
|
.. _Mako: https://www.makotemplates.org/
|
|
|
|
How Compatible is Jinja with Django?
|
|
------------------------------------
|
|
|
|
The default syntax of Jinja matches Django syntax in many ways. However
|
|
this similarity doesn't mean that you can use a Django template unmodified
|
|
in Jinja. For example filter arguments use a function call syntax rather
|
|
than a colon to separate filter name and arguments. Additionally the
|
|
extension interface in Jinja is fundamentally different from the Django one
|
|
which means that your custom tags won't work any longer.
|
|
|
|
Generally speaking you will use much less custom extensions as the Jinja
|
|
template system allows you to use a certain subset of Python expressions
|
|
which can replace most Django extensions. For example instead of using
|
|
something like this::
|
|
|
|
{% load comments %}
|
|
{% get_latest_comments 10 as latest_comments %}
|
|
{% for comment in latest_comments %}
|
|
...
|
|
{% endfor %}
|
|
|
|
You will most likely provide an object with attributes to retrieve
|
|
comments from the database::
|
|
|
|
{% for comment in models.comments.latest(10) %}
|
|
...
|
|
{% endfor %}
|
|
|
|
Or directly provide the model for quick testing::
|
|
|
|
{% for comment in Comment.objects.order_by('-pub_date')[:10] %}
|
|
...
|
|
{% endfor %}
|
|
|
|
Please keep in mind that even though you may put such things into templates
|
|
it still isn't a good idea. Queries should go into the view code and not
|
|
the template!
|
|
|
|
Isn't it a terrible idea to put Logic into Templates?
|
|
-----------------------------------------------------
|
|
|
|
Without a doubt you should try to remove as much logic from templates as
|
|
possible. But templates without any logic mean that you have to do all
|
|
the processing in the code which is boring and stupid. A template engine
|
|
that does that is shipped with Python and called `string.Template`. Comes
|
|
without loops and if conditions and is by far the fastest template engine
|
|
you can get for Python.
|
|
|
|
So some amount of logic is required in templates to keep everyone happy.
|
|
And Jinja leaves it pretty much to you how much logic you want to put into
|
|
templates. There are some restrictions in what you can do and what not.
|
|
|
|
Jinja neither allows you to put arbitrary Python code into templates nor
|
|
does it allow all Python expressions. The operators are limited to the
|
|
most common ones and more advanced expressions such as list comprehensions
|
|
and generator expressions are not supported. This keeps the template engine
|
|
easier to maintain and templates more readable.
|
|
|
|
Why is Autoescaping not the Default?
|
|
------------------------------------
|
|
|
|
There are multiple reasons why automatic escaping is not the default mode
|
|
and also not the recommended one. While automatic escaping of variables
|
|
means that you will less likely have an XSS problem it also causes a huge
|
|
amount of extra processing in the template engine which can cause serious
|
|
performance problems. As Python doesn't provide a way to mark strings as
|
|
unsafe Jinja has to hack around that limitation by providing a custom
|
|
string class (the :class:`Markup` string) that safely interacts with safe
|
|
and unsafe strings.
|
|
|
|
With explicit escaping however the template engine doesn't have to perform
|
|
any safety checks on variables. Also a human knows not to escape integers
|
|
or strings that may never contain characters one has to escape or already
|
|
HTML markup. For example when iterating over a list over a table of
|
|
integers and floats for a table of statistics the template designer can
|
|
omit the escaping because he knows that integers or floats don't contain
|
|
any unsafe parameters.
|
|
|
|
Additionally Jinja is a general purpose template engine and not only used
|
|
for HTML/XML generation. For example you may generate LaTeX, emails,
|
|
CSS, JavaScript, or configuration files.
|
|
|
|
Why is the Context immutable?
|
|
-----------------------------
|
|
|
|
When writing a :func:`contextfunction` or something similar you may have
|
|
noticed that the context tries to stop you from modifying it. If you have
|
|
managed to modify the context by using an internal context API you may
|
|
have noticed that changes in the context don't seem to be visible in the
|
|
template. The reason for this is that Jinja uses the context only as
|
|
primary data source for template variables for performance reasons.
|
|
|
|
If you want to modify the context write a function that returns a variable
|
|
instead that one can assign to a variable by using set::
|
|
|
|
{% set comments = get_latest_comments() %}
|
|
|
|
My tracebacks look weird. What's happening?
|
|
-------------------------------------------
|
|
|
|
Jinja can rewrite tracebacks so they show the template lines numbers and
|
|
source rather than the underlying compiled code, but this requires
|
|
special Python support. CPython <3.7 requires ``ctypes``, and PyPy
|
|
requires transparent proxy support.
|
|
|
|
If you are using Google App Engine, ``ctypes`` is not available. You can
|
|
make it available in development, but not in production.
|
|
|
|
.. code-block:: python
|
|
|
|
import os
|
|
if os.environ.get('SERVER_SOFTWARE', '').startswith('Dev'):
|
|
from google.appengine.tools.devappserver2.python import sandbox
|
|
sandbox._WHITE_LIST_C_MODULES += ['_ctypes', 'gestalt']
|
|
|
|
Credit for this snippet goes to `Thomas Johansson
|
|
<https://stackoverflow.com/questions/3086091/debug-jinja2-in-google-app-engine/3694434#3694434>`_
|
|
|
|
My Macros are overridden by something
|
|
-------------------------------------
|
|
|
|
In some situations the Jinja scoping appears arbitrary:
|
|
|
|
layout.tmpl:
|
|
|
|
.. sourcecode:: jinja
|
|
|
|
{% macro foo() %}LAYOUT{% endmacro %}
|
|
{% block body %}{% endblock %}
|
|
|
|
child.tmpl:
|
|
|
|
.. sourcecode:: jinja
|
|
|
|
{% extends 'layout.tmpl' %}
|
|
{% macro foo() %}CHILD{% endmacro %}
|
|
{% block body %}{{ foo() }}{% endblock %}
|
|
|
|
This will print ``LAYOUT`` in Jinja. This is a side effect of having
|
|
the parent template evaluated after the child one. This allows child
|
|
templates passing information to the parent template. To avoid this
|
|
issue rename the macro or variable in the parent template to have an
|
|
uncommon prefix.
|
|
|
|
.. _Jinja 1: https://pypi.org/project/Jinja/
|