summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:06:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:06:13 +0000
commitce859b2defe1fc90c7a16551291799fc37284add (patch)
tree7e6b04791662f8f268c7abc9c07d41e98a261a84 /docs
parentInitial commit. (diff)
downloadjinja2-upstream.tar.xz
jinja2-upstream.zip
Adding upstream version 3.1.2.upstream/3.1.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'docs')
-rw-r--r--docs/Makefile19
-rw-r--r--docs/_static/jinja-logo-sidebar.pngbin0 -> 10484 bytes
-rw-r--r--docs/_static/jinja-logo.pngbin0 -> 12854 bytes
-rw-r--r--docs/api.rst922
-rw-r--r--docs/changes.rst4
-rw-r--r--docs/conf.py53
-rw-r--r--docs/examples/cache_extension.py54
-rw-r--r--docs/examples/inline_gettext_extension.py72
-rw-r--r--docs/extensions.rst423
-rw-r--r--docs/faq.rst75
-rw-r--r--docs/index.rst29
-rw-r--r--docs/integration.rst94
-rw-r--r--docs/intro.rst63
-rw-r--r--docs/license.rst4
-rw-r--r--docs/make.bat35
-rw-r--r--docs/nativetypes.rst64
-rw-r--r--docs/sandbox.rst111
-rw-r--r--docs/switching.rst181
-rw-r--r--docs/templates.rst1949
-rw-r--r--docs/tricks.rst100
20 files changed, 4252 insertions, 0 deletions
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..5128596
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,19 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/jinja-logo-sidebar.png b/docs/_static/jinja-logo-sidebar.png
new file mode 100644
index 0000000..455b4c3
--- /dev/null
+++ b/docs/_static/jinja-logo-sidebar.png
Binary files differ
diff --git a/docs/_static/jinja-logo.png b/docs/_static/jinja-logo.png
new file mode 100644
index 0000000..7f8ca5b
--- /dev/null
+++ b/docs/_static/jinja-logo.png
Binary files differ
diff --git a/docs/api.rst b/docs/api.rst
new file mode 100644
index 0000000..b2db537
--- /dev/null
+++ b/docs/api.rst
@@ -0,0 +1,922 @@
+API
+===
+
+.. module:: jinja2
+ :noindex:
+ :synopsis: public Jinja API
+
+This document describes the API to Jinja and not the template language
+(for that, see :doc:`/templates`). It will be most useful as reference
+to those implementing the template interface to the application and not
+those who are creating Jinja templates.
+
+Basics
+------
+
+Jinja uses a central object called the template :class:`Environment`.
+Instances of this class are used to store the configuration and global objects,
+and are used to load templates from the file system or other locations.
+Even if you are creating templates from strings by using the constructor of
+:class:`Template` class, an environment is created automatically for you,
+albeit a shared one.
+
+Most applications will create one :class:`Environment` object on application
+initialization and use that to load templates. In some cases however, it's
+useful to have multiple environments side by side, if different configurations
+are in use.
+
+The simplest way to configure Jinja to load templates for your
+application is to use :class:`~loaders.PackageLoader`.
+
+.. code-block:: python
+
+ from jinja2 import Environment, PackageLoader, select_autoescape
+ env = Environment(
+ loader=PackageLoader("yourapp"),
+ autoescape=select_autoescape()
+ )
+
+This will create a template environment with a loader that looks up
+templates in the ``templates`` folder inside the ``yourapp`` Python
+package (or next to the ``yourapp.py`` Python module). It also enables
+autoescaping for HTML files. This loader only requires that ``yourapp``
+is importable, it figures out the absolute path to the folder for you.
+
+Different loaders are available to load templates in other ways or from
+other locations. They're listed in the `Loaders`_ section below. You can
+also write your own if you want to load templates from a source that's
+more specialized to your project.
+
+To load a template from this environment, call the :meth:`get_template`
+method, which returns the loaded :class:`Template`.
+
+.. code-block:: python
+
+ template = env.get_template("mytemplate.html")
+
+To render it with some variables, call the :meth:`render` method.
+
+.. code-block:: python
+
+ print(template.render(the="variables", go="here"))
+
+Using a template loader rather than passing strings to :class:`Template`
+or :meth:`Environment.from_string` has multiple advantages. Besides being
+a lot easier to use it also enables template inheritance.
+
+.. admonition:: Notes on Autoescaping
+
+ In future versions of Jinja we might enable autoescaping by default
+ for security reasons. As such you are encouraged to explicitly
+ configure autoescaping now instead of relying on the default.
+
+
+High Level API
+--------------
+
+The high-level API is the API you will use in the application to load and
+render Jinja templates. The :ref:`low-level-api` on the other side is only
+useful if you want to dig deeper into Jinja or :ref:`develop extensions
+<jinja-extensions>`.
+
+.. autoclass:: Environment([options])
+ :members: from_string, get_template, select_template,
+ get_or_select_template, join_path, extend, compile_expression,
+ compile_templates, list_templates, add_extension
+
+ .. attribute:: shared
+
+ If a template was created by using the :class:`Template` constructor
+ an environment is created automatically. These environments are
+ created as shared environments which means that multiple templates
+ may have the same anonymous environment. For all shared environments
+ this attribute is `True`, else `False`.
+
+ .. attribute:: sandboxed
+
+ If the environment is sandboxed this attribute is `True`. For the
+ sandbox mode have a look at the documentation for the
+ :class:`~jinja2.sandbox.SandboxedEnvironment`.
+
+ .. attribute:: filters
+
+ A dict of filters for this environment. As long as no template was
+ loaded it's safe to add new filters or remove old. For custom filters
+ see :ref:`writing-filters`. For valid filter names have a look at
+ :ref:`identifier-naming`.
+
+ .. attribute:: tests
+
+ A dict of test functions for this environment. As long as no
+ template was loaded it's safe to modify this dict. For custom tests
+ see :ref:`writing-tests`. For valid test names have a look at
+ :ref:`identifier-naming`.
+
+ .. attribute:: globals
+
+ A dict of variables that are available in every template loaded
+ by the environment. As long as no template was loaded it's safe
+ to modify this. For more details see :ref:`global-namespace`.
+ For valid object names see :ref:`identifier-naming`.
+
+ .. attribute:: policies
+
+ A dictionary with :ref:`policies`. These can be reconfigured to
+ change the runtime behavior or certain template features. Usually
+ these are security related.
+
+ .. attribute:: code_generator_class
+
+ The class used for code generation. This should not be changed
+ in most cases, unless you need to modify the Python code a
+ template compiles to.
+
+ .. attribute:: context_class
+
+ The context used for templates. This should not be changed
+ in most cases, unless you need to modify internals of how
+ template variables are handled. For details, see
+ :class:`~jinja2.runtime.Context`.
+
+ .. automethod:: overlay([options])
+
+ .. method:: undefined([hint, obj, name, exc])
+
+ Creates a new :class:`Undefined` object for `name`. This is useful
+ for filters or functions that may return undefined objects for
+ some operations. All parameters except of `hint` should be provided
+ as keyword parameters for better readability. The `hint` is used as
+ error message for the exception if provided, otherwise the error
+ message will be generated from `obj` and `name` automatically. The exception
+ provided as `exc` is raised if something with the generated undefined
+ object is done that the undefined object does not allow. The default
+ exception is :exc:`UndefinedError`. If a `hint` is provided the
+ `name` may be omitted.
+
+ The most common way to create an undefined object is by providing
+ a name only::
+
+ return environment.undefined(name='some_name')
+
+ This means that the name `some_name` is not defined. If the name
+ was from an attribute of an object it makes sense to tell the
+ undefined object the holder object to improve the error message::
+
+ if not hasattr(obj, 'attr'):
+ return environment.undefined(obj=obj, name='attr')
+
+ For a more complex example you can provide a hint. For example
+ the :func:`first` filter creates an undefined object that way::
+
+ return environment.undefined('no first item, sequence was empty')
+
+ If it the `name` or `obj` is known (for example because an attribute
+ was accessed) it should be passed to the undefined object, even if
+ a custom `hint` is provided. This gives undefined objects the
+ possibility to enhance the error message.
+
+.. autoclass:: Template
+ :members: module, make_module
+
+ .. attribute:: globals
+
+ A dict of variables that are available every time the template
+ is rendered, without needing to pass them during render. This
+ should not be modified, as depending on how the template was
+ loaded it may be shared with the environment and other
+ templates.
+
+ Defaults to :attr:`Environment.globals` unless extra values are
+ passed to :meth:`Environment.get_template`.
+
+ Globals are only intended for data that is common to every
+ render of the template. Specific data should be passed to
+ :meth:`render`.
+
+ See :ref:`global-namespace`.
+
+ .. attribute:: name
+
+ The loading name of the template. If the template was loaded from a
+ string this is `None`.
+
+ .. attribute:: filename
+
+ The filename of the template on the file system if it was loaded from
+ there. Otherwise this is `None`.
+
+ .. automethod:: render([context])
+
+ .. automethod:: generate([context])
+
+ .. automethod:: stream([context])
+
+ .. automethod:: render_async([context])
+
+ .. automethod:: generate_async([context])
+
+
+.. autoclass:: jinja2.environment.TemplateStream()
+ :members: disable_buffering, enable_buffering, dump
+
+
+Autoescaping
+------------
+
+.. versionchanged:: 2.4
+
+Jinja now comes with autoescaping support. As of Jinja 2.9 the
+autoescape extension is removed and built-in. However autoescaping is
+not yet enabled by default though this will most likely change in the
+future. It's recommended to configure a sensible default for
+autoescaping. This makes it possible to enable and disable autoescaping
+on a per-template basis (HTML versus text for instance).
+
+.. autofunction:: jinja2.select_autoescape
+
+Here a recommended setup that enables autoescaping for templates ending
+in ``'.html'``, ``'.htm'`` and ``'.xml'`` and disabling it by default
+for all other extensions. You can use the :func:`~jinja2.select_autoescape`
+function for this::
+
+ from jinja2 import Environment, PackageLoader, select_autoescape
+ env = Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
+ loader=PackageLoader('mypackage'))
+
+The :func:`~jinja.select_autoescape` function returns a function that
+works roughly like this::
+
+ def autoescape(template_name):
+ if template_name is None:
+ return False
+ if template_name.endswith(('.html', '.htm', '.xml'))
+
+When implementing a guessing autoescape function, make sure you also
+accept `None` as valid template name. This will be passed when generating
+templates from strings. You should always configure autoescaping as
+defaults in the future might change.
+
+Inside the templates the behaviour can be temporarily changed by using
+the `autoescape` block (see :ref:`autoescape-overrides`).
+
+
+.. _identifier-naming:
+
+Notes on Identifiers
+--------------------
+
+Jinja uses Python naming rules. Valid identifiers can be any combination
+of characters accepted by Python.
+
+Filters and tests are looked up in separate namespaces and have slightly
+modified identifier syntax. Filters and tests may contain dots to group
+filters and tests by topic. For example it's perfectly valid to add a
+function into the filter dict and call it `to.str`. The regular
+expression for filter and test identifiers is
+``[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*``.
+
+
+Undefined Types
+---------------
+
+These classes can be used as undefined types. The :class:`Environment`
+constructor takes an `undefined` parameter that can be one of those classes
+or a custom subclass of :class:`Undefined`. Whenever the template engine is
+unable to look up a name or access an attribute one of those objects is
+created and returned. Some operations on undefined values are then allowed,
+others fail.
+
+The closest to regular Python behavior is the :class:`StrictUndefined` which
+disallows all operations beside testing if it's an undefined object.
+
+.. autoclass:: jinja2.Undefined()
+
+ .. attribute:: _undefined_hint
+
+ Either `None` or a string with the error message for the
+ undefined object.
+
+ .. attribute:: _undefined_obj
+
+ Either `None` or the owner object that caused the undefined object
+ to be created (for example because an attribute does not exist).
+
+ .. attribute:: _undefined_name
+
+ The name for the undefined variable / attribute or just `None`
+ if no such information exists.
+
+ .. attribute:: _undefined_exception
+
+ The exception that the undefined object wants to raise. This
+ is usually one of :exc:`UndefinedError` or :exc:`SecurityError`.
+
+ .. method:: _fail_with_undefined_error(\*args, \**kwargs)
+
+ When called with any arguments this method raises
+ :attr:`_undefined_exception` with an error message generated
+ from the undefined hints stored on the undefined object.
+
+.. autoclass:: jinja2.ChainableUndefined()
+
+.. autoclass:: jinja2.DebugUndefined()
+
+.. autoclass:: jinja2.StrictUndefined()
+
+There is also a factory function that can decorate undefined objects to
+implement logging on failures:
+
+.. autofunction:: jinja2.make_logging_undefined
+
+Undefined objects are created by calling :attr:`undefined`.
+
+.. admonition:: Implementation
+
+ :class:`Undefined` is implemented by overriding the special
+ ``__underscore__`` methods. For example the default
+ :class:`Undefined` class implements ``__str__`` to returns an empty
+ string, while ``__int__`` and others fail with an exception. To
+ allow conversion to int by returning ``0`` you can implement your
+ own subclass.
+
+ .. code-block:: python
+
+ class NullUndefined(Undefined):
+ def __int__(self):
+ return 0
+
+ def __float__(self):
+ return 0.0
+
+ To disallow a method, override it and raise
+ :attr:`~Undefined._undefined_exception`. Because this is very
+ common there is the helper method
+ :meth:`~Undefined._fail_with_undefined_error` that raises the error
+ with the correct information. Here's a class that works like the
+ regular :class:`Undefined` but fails on iteration::
+
+ class NonIterableUndefined(Undefined):
+ def __iter__(self):
+ self._fail_with_undefined_error()
+
+
+The Context
+-----------
+
+.. autoclass:: jinja2.runtime.Context()
+ :members: get, resolve, resolve_or_missing, get_exported, get_all
+
+ .. attribute:: parent
+
+ A dict of read only, global variables the template looks up. These
+ can either come from another :class:`Context`, from the
+ :attr:`Environment.globals` or :attr:`Template.globals` or points
+ to a dict created by combining the globals with the variables
+ passed to the render function. It must not be altered.
+
+ .. attribute:: vars
+
+ The template local variables. This list contains environment and
+ context functions from the :attr:`parent` scope as well as local
+ modifications and exported variables from the template. The template
+ will modify this dict during template evaluation but filters and
+ context functions are not allowed to modify it.
+
+ .. attribute:: environment
+
+ The environment that loaded the template.
+
+ .. attribute:: exported_vars
+
+ This set contains all the names the template exports. The values for
+ the names are in the :attr:`vars` dict. In order to get a copy of the
+ exported variables as dict, :meth:`get_exported` can be used.
+
+ .. attribute:: name
+
+ The load name of the template owning this context.
+
+ .. attribute:: blocks
+
+ A dict with the current mapping of blocks in the template. The keys
+ in this dict are the names of the blocks, and the values a list of
+ blocks registered. The last item in each list is the current active
+ block (latest in the inheritance chain).
+
+ .. attribute:: eval_ctx
+
+ The current :ref:`eval-context`.
+
+ .. automethod:: jinja2.runtime.Context.call(callable, \*args, \**kwargs)
+
+
+The context is immutable, it prevents modifications, and if it is
+modified somehow despite that those changes may not show up. For
+performance, Jinja does not use the context as data storage for, only as
+a primary data source. Variables that the template does not define are
+looked up in the context, but variables the template does define are
+stored locally.
+
+Instead of modifying the context directly, a function should return
+a value that can be assigned to a variable within the template itself.
+
+.. code-block:: jinja
+
+ {% set comments = get_latest_comments() %}
+
+
+.. _loaders:
+
+Loaders
+-------
+
+Loaders are responsible for loading templates from a resource such as the
+file system. The environment will keep the compiled modules in memory like
+Python's `sys.modules`. Unlike `sys.modules` however this cache is limited in
+size by default and templates are automatically reloaded.
+All loaders are subclasses of :class:`BaseLoader`. If you want to create your
+own loader, subclass :class:`BaseLoader` and override `get_source`.
+
+.. autoclass:: jinja2.BaseLoader
+ :members: get_source, load
+
+Here a list of the builtin loaders Jinja provides:
+
+.. autoclass:: jinja2.FileSystemLoader
+
+.. autoclass:: jinja2.PackageLoader
+
+.. autoclass:: jinja2.DictLoader
+
+.. autoclass:: jinja2.FunctionLoader
+
+.. autoclass:: jinja2.PrefixLoader
+
+.. autoclass:: jinja2.ChoiceLoader
+
+.. autoclass:: jinja2.ModuleLoader
+
+
+.. _bytecode-cache:
+
+Bytecode Cache
+--------------
+
+Jinja 2.1 and higher support external bytecode caching. Bytecode caches make
+it possible to store the generated bytecode on the file system or a different
+location to avoid parsing the templates on first use.
+
+This is especially useful if you have a web application that is initialized on
+the first request and Jinja compiles many templates at once which slows down
+the application.
+
+To use a bytecode cache, instantiate it and pass it to the :class:`Environment`.
+
+.. autoclass:: jinja2.BytecodeCache
+ :members: load_bytecode, dump_bytecode, clear
+
+.. autoclass:: jinja2.bccache.Bucket
+ :members: write_bytecode, load_bytecode, bytecode_from_string,
+ bytecode_to_string, reset
+
+ .. attribute:: environment
+
+ The :class:`Environment` that created the bucket.
+
+ .. attribute:: key
+
+ The unique cache key for this bucket
+
+ .. attribute:: code
+
+ The bytecode if it's loaded, otherwise `None`.
+
+
+Builtin bytecode caches:
+
+.. autoclass:: jinja2.FileSystemBytecodeCache
+
+.. autoclass:: jinja2.MemcachedBytecodeCache
+
+
+Async Support
+-------------
+
+.. versionadded:: 2.9
+
+Jinja supports the Python ``async`` and ``await`` syntax. For the
+template designer, this support (when enabled) is entirely transparent,
+templates continue to look exactly the same. However, developers should
+be aware of the implementation as it affects what types of APIs you can
+use.
+
+By default, async support is disabled. Enabling it will cause the
+environment to compile different code behind the scenes in order to
+handle async and sync code in an asyncio event loop. This has the
+following implications:
+
+- Template rendering requires an event loop to be available to the
+ current thread. :func:`asyncio.get_running_loop` must return an
+ event loop.
+- The compiled code uses ``await`` for functions and attributes, and
+ uses ``async for`` loops. In order to support using both async and
+ sync functions in this context, a small wrapper is placed around
+ all calls and access, which adds overhead compared to purely async
+ code.
+- Sync methods and filters become wrappers around their corresponding
+ async implementations where needed. For example, ``render`` invokes
+ ``async_render``, and ``|map`` supports async iterables.
+
+Awaitable objects can be returned from functions in templates and any
+function call in a template will automatically await the result. The
+``await`` you would normally add in Python is implied. For example, you
+can provide a method that asynchronously loads data from a database, and
+from the template designer's point of view it can be called like any
+other function.
+
+
+.. _policies:
+
+Policies
+--------
+
+Starting with Jinja 2.9 policies can be configured on the environment
+which can slightly influence how filters and other template constructs
+behave. They can be configured with the
+:attr:`~jinja2.Environment.policies` attribute.
+
+Example::
+
+ env.policies['urlize.rel'] = 'nofollow noopener'
+
+``truncate.leeway``:
+ Configures the leeway default for the `truncate` filter. Leeway as
+ introduced in 2.9 but to restore compatibility with older templates
+ it can be configured to `0` to get the old behavior back. The default
+ is `5`.
+
+``urlize.rel``:
+ A string that defines the items for the `rel` attribute of generated
+ links with the `urlize` filter. These items are always added. The
+ default is `noopener`.
+
+``urlize.target``:
+ The default target that is issued for links from the `urlize` filter
+ if no other target is defined by the call explicitly.
+
+``urlize.extra_schemes``:
+ Recognize URLs that start with these schemes in addition to the
+ default ``http://``, ``https://``, and ``mailto:``.
+
+``json.dumps_function``:
+ If this is set to a value other than `None` then the `tojson` filter
+ will dump with this function instead of the default one. Note that
+ this function should accept arbitrary extra arguments which might be
+ passed in the future from the filter. Currently the only argument
+ that might be passed is `indent`. The default dump function is
+ ``json.dumps``.
+
+``json.dumps_kwargs``:
+ Keyword arguments to be passed to the dump function. The default is
+ ``{'sort_keys': True}``.
+
+.. _ext-i18n-trimmed:
+
+``ext.i18n.trimmed``:
+ If this is set to `True`, ``{% trans %}`` blocks of the
+ :ref:`i18n-extension` will always unify linebreaks and surrounding
+ whitespace as if the `trimmed` modifier was used.
+
+
+Utilities
+---------
+
+These helper functions and classes are useful if you add custom filters or
+functions to a Jinja environment.
+
+.. autofunction:: jinja2.pass_context
+
+.. autofunction:: jinja2.pass_eval_context
+
+.. autofunction:: jinja2.pass_environment
+
+.. autofunction:: jinja2.clear_caches
+
+.. autofunction:: jinja2.is_undefined
+
+
+Exceptions
+----------
+
+.. autoexception:: jinja2.TemplateError
+
+.. autoexception:: jinja2.UndefinedError
+
+.. autoexception:: jinja2.TemplateNotFound
+
+.. autoexception:: jinja2.TemplatesNotFound
+
+.. autoexception:: jinja2.TemplateSyntaxError
+
+ .. attribute:: message
+
+ The error message.
+
+ .. attribute:: lineno
+
+ The line number where the error occurred.
+
+ .. attribute:: name
+
+ The load name for the template.
+
+ .. attribute:: filename
+
+ The filename that loaded the template in the encoding of the
+ file system (most likely utf-8, or mbcs on Windows systems).
+
+.. autoexception:: jinja2.TemplateRuntimeError
+
+.. autoexception:: jinja2.TemplateAssertionError
+
+
+.. _writing-filters:
+
+Custom Filters
+--------------
+
+Filters are Python functions that take the value to the left of the
+filter as the first argument and produce a new value. Arguments passed
+to the filter are passed after the value.
+
+For example, the filter ``{{ 42|myfilter(23) }}`` is called behind the
+scenes as ``myfilter(42, 23)``.
+
+Jinja comes with some :ref:`built-in filters <builtin-filters>`. To use
+a custom filter, write a function that takes at least a ``value``
+argument, then register it in :attr:`Environment.filters`.
+
+Here's a filter that formats datetime objects:
+
+.. code-block:: python
+
+ def datetime_format(value, format="%H:%M %d-%m-%y"):
+ return value.strftime(format)
+
+ environment.filters["datetime_format"] = datetime_format
+
+Now it can be used in templates:
+
+.. sourcecode:: jinja
+
+ {{ article.pub_date|datetimeformat }}
+ {{ article.pub_date|datetimeformat("%B %Y") }}
+
+Some decorators are available to tell Jinja to pass extra information to
+the filter. The object is passed as the first argument, making the value
+being filtered the second argument.
+
+- :func:`pass_environment` passes the :class:`Environment`.
+- :func:`pass_eval_context` passes the :ref:`eval-context`.
+- :func:`pass_context` passes the current
+ :class:`~jinja2.runtime.Context`.
+
+Here's a filter that converts line breaks into HTML ``<br>`` and ``<p>``
+tags. It uses the eval context to check if autoescape is currently
+enabled before escaping the input and marking the output safe.
+
+.. code-block:: python
+
+ import re
+ from jinja2 import pass_eval_context
+ from markupsafe import Markup, escape
+
+ @pass_eval_context
+ def nl2br(eval_ctx, value):
+ br = "<br>\n"
+
+ if eval_ctx.autoescape:
+ value = escape(value)
+ br = Markup(br)
+
+ result = "\n\n".join(
+ f"<p>{br.join(p.splitlines())}<\p>"
+ for p in re.split(r"(?:\r\n|\r(?!\n)|\n){2,}", value)
+ )
+ return Markup(result) if autoescape else result
+
+
+.. _writing-tests:
+
+Custom Tests
+------------
+
+Test are Python functions that take the value to the left of the test as
+the first argument, and return ``True`` or ``False``. Arguments passed
+to the test are passed after the value.
+
+For example, the test ``{{ 42 is even }}`` is called behind the scenes
+as ``is_even(42)``.
+
+Jinja comes with some :ref:`built-in tests <builtin-tests>`. To use a
+custom tests, write a function that takes at least a ``value`` argument,
+then register it in :attr:`Environment.tests`.
+
+Here's a test that checks if a value is a prime number:
+
+.. code-block:: python
+
+ import math
+
+ def is_prime(n):
+ if n == 2:
+ return True
+
+ for i in range(2, int(math.ceil(math.sqrt(n))) + 1):
+ if n % i == 0:
+ return False
+
+ return True
+
+ environment.tests["prime"] = is_prime
+
+Now it can be used in templates:
+
+.. sourcecode:: jinja
+
+ {% if value is prime %}
+ {{ value }} is a prime number
+ {% else %}
+ {{ value }} is not a prime number
+ {% endif %}
+
+Some decorators are available to tell Jinja to pass extra information to
+the filter. The object is passed as the first argument, making the value
+being filtered the second argument.
+
+- :func:`pass_environment` passes the :class:`Environment`.
+- :func:`pass_eval_context` passes the :ref:`eval-context`.
+- :func:`pass_context` passes the current
+ :class:`~jinja2.runtime.Context`.
+
+
+.. _eval-context:
+
+Evaluation Context
+------------------
+
+The evaluation context (short eval context or eval ctx) makes it
+possible to activate and deactivate compiled features at runtime.
+
+Currently it is only used to enable and disable automatic escaping, but
+it can be used by extensions as well.
+
+The ``autoescape`` setting should be checked on the evaluation context,
+not the environment. The evaluation context will have the computed value
+for the current template.
+
+Instead of ``pass_environment``:
+
+.. code-block:: python
+
+ @pass_environment
+ def filter(env, value):
+ result = do_something(value)
+
+ if env.autoescape:
+ result = Markup(result)
+
+ return result
+
+Use ``pass_eval_context`` if you only need the setting:
+
+.. code-block:: python
+
+ @pass_eval_context
+ def filter(eval_ctx, value):
+ result = do_something(value)
+
+ if eval_ctx.autoescape:
+ result = Markup(result)
+
+ return result
+
+Or use ``pass_context`` if you need other context behavior as well:
+
+.. code-block:: python
+
+ @pass_context
+ def filter(context, value):
+ result = do_something(value)
+
+ if context.eval_ctx.autoescape:
+ result = Markup(result)
+
+ return result
+
+The evaluation context must not be modified at runtime. Modifications
+must only happen with a :class:`nodes.EvalContextModifier` and
+:class:`nodes.ScopedEvalContextModifier` from an extension, not on the
+eval context object itself.
+
+.. autoclass:: jinja2.nodes.EvalContext
+
+ .. attribute:: autoescape
+
+ `True` or `False` depending on if autoescaping is active or not.
+
+ .. attribute:: volatile
+
+ `True` if the compiler cannot evaluate some expressions at compile
+ time. At runtime this should always be `False`.
+
+
+.. _global-namespace:
+
+The Global Namespace
+--------------------
+
+The global namespace stores variables and functions that should be
+available without needing to pass them to :meth:`Template.render`. They
+are also available to templates that are imported or included without
+context. Most applications should only use :attr:`Environment.globals`.
+
+:attr:`Environment.globals` are intended for data that is common to all
+templates loaded by that environment. :attr:`Template.globals` are
+intended for data that is common to all renders of that template, and
+default to :attr:`Environment.globals` unless they're given in
+:meth:`Environment.get_template`, etc. Data that is specific to a
+render should be passed as context to :meth:`Template.render`.
+
+Only one set of globals is used during any specific rendering. If
+templates A and B both have template globals, and B extends A, then
+only B's globals are used for both when using ``b.render()``.
+
+Environment globals should not be changed after loading any templates,
+and template globals should not be changed at any time after loading the
+template. Changing globals after loading a template will result in
+unexpected behavior as they may be shared between the environment and
+other templates.
+
+
+.. _low-level-api:
+
+Low Level API
+-------------
+
+The low level API exposes functionality that can be useful to understand some
+implementation details, debugging purposes or advanced :ref:`extension
+<jinja-extensions>` techniques. Unless you know exactly what you are doing we
+don't recommend using any of those.
+
+.. automethod:: Environment.lex
+
+.. automethod:: Environment.parse
+
+.. automethod:: Environment.preprocess
+
+.. automethod:: Template.new_context
+
+.. method:: Template.root_render_func(context)
+
+ This is the low level render function. It's passed a :class:`Context`
+ that has to be created by :meth:`new_context` of the same template or
+ a compatible template. This render function is generated by the
+ compiler from the template code and returns a generator that yields
+ strings.
+
+ If an exception in the template code happens the template engine will
+ not rewrite the exception but pass through the original one. As a
+ matter of fact this function should only be called from within a
+ :meth:`render` / :meth:`generate` / :meth:`stream` call.
+
+.. attribute:: Template.blocks
+
+ A dict of block render functions. Each of these functions works exactly
+ like the :meth:`root_render_func` with the same limitations.
+
+.. attribute:: Template.is_up_to_date
+
+ This attribute is `False` if there is a newer version of the template
+ available, otherwise `True`.
+
+.. admonition:: Note
+
+ The low-level API is fragile. Future Jinja versions will try not to
+ change it in a backwards incompatible way but modifications in the Jinja
+ core may shine through. For example if Jinja introduces a new AST node
+ in later versions that may be returned by :meth:`~Environment.parse`.
+
+The Meta API
+------------
+
+.. versionadded:: 2.2
+
+The meta API returns some information about abstract syntax trees that
+could help applications to implement more advanced template concepts. All
+the functions of the meta API operate on an abstract syntax tree as
+returned by the :meth:`Environment.parse` method.
+
+.. autofunction:: jinja2.meta.find_undeclared_variables
+
+.. autofunction:: jinja2.meta.find_referenced_templates
diff --git a/docs/changes.rst b/docs/changes.rst
new file mode 100644
index 0000000..955deaf
--- /dev/null
+++ b/docs/changes.rst
@@ -0,0 +1,4 @@
+Changes
+=======
+
+.. include:: ../CHANGES.rst
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..f65d462
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,53 @@
+from pallets_sphinx_themes import get_version
+from pallets_sphinx_themes import ProjectLink
+
+# Project --------------------------------------------------------------
+
+project = "Jinja"
+copyright = "2007 Pallets"
+author = "Pallets"
+release, version = get_version("Jinja2")
+
+# General --------------------------------------------------------------
+
+master_doc = "index"
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.intersphinx",
+ "pallets_sphinx_themes",
+ "sphinxcontrib.log_cabinet",
+ "sphinx_issues",
+]
+autodoc_typehints = "description"
+intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)}
+issues_github_path = "pallets/jinja"
+
+# HTML -----------------------------------------------------------------
+
+html_theme = "jinja"
+html_theme_options = {"index_sidebar_logo": False}
+html_context = {
+ "project_links": [
+ ProjectLink("Donate", "https://palletsprojects.com/donate"),
+ ProjectLink("PyPI Releases", "https://pypi.org/project/Jinja2/"),
+ ProjectLink("Source Code", "https://github.com/pallets/jinja/"),
+ ProjectLink("Issue Tracker", "https://github.com/pallets/jinja/issues/"),
+ ProjectLink("Website", "https://palletsprojects.com/p/jinja/"),
+ ProjectLink("Twitter", "https://twitter.com/PalletsTeam"),
+ ProjectLink("Chat", "https://discord.gg/pallets"),
+ ]
+}
+html_sidebars = {
+ "index": ["project.html", "localtoc.html", "searchbox.html", "ethicalads.html"],
+ "**": ["localtoc.html", "relations.html", "searchbox.html", "ethicalads.html"],
+}
+singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]}
+html_static_path = ["_static"]
+html_favicon = "_static/jinja-logo-sidebar.png"
+html_logo = "_static/jinja-logo-sidebar.png"
+html_title = f"Jinja Documentation ({version})"
+html_show_sourcelink = False
+
+# LaTeX ----------------------------------------------------------------
+
+latex_documents = [(master_doc, f"Jinja-{version}.tex", html_title, author, "manual")]
diff --git a/docs/examples/cache_extension.py b/docs/examples/cache_extension.py
new file mode 100644
index 0000000..46af67c
--- /dev/null
+++ b/docs/examples/cache_extension.py
@@ -0,0 +1,54 @@
+from jinja2 import nodes
+from jinja2.ext import Extension
+
+
+class FragmentCacheExtension(Extension):
+ # a set of names that trigger the extension.
+ tags = {"cache"}
+
+ def __init__(self, environment):
+ super().__init__(environment)
+
+ # add the defaults to the environment
+ environment.extend(fragment_cache_prefix="", fragment_cache=None)
+
+ def parse(self, parser):
+ # the first token is the token that started the tag. In our case
+ # we only listen to ``'cache'`` so this will be a name token with
+ # `cache` as value. We get the line number so that we can give
+ # that line number to the nodes we create by hand.
+ lineno = next(parser.stream).lineno
+
+ # now we parse a single expression that is used as cache key.
+ args = [parser.parse_expression()]
+
+ # if there is a comma, the user provided a timeout. If not use
+ # None as second parameter.
+ if parser.stream.skip_if("comma"):
+ args.append(parser.parse_expression())
+ else:
+ args.append(nodes.Const(None))
+
+ # now we parse the body of the cache block up to `endcache` and
+ # drop the needle (which would always be `endcache` in that case)
+ body = parser.parse_statements(["name:endcache"], drop_needle=True)
+
+ # now return a `CallBlock` node that calls our _cache_support
+ # helper method on this extension.
+ return nodes.CallBlock(
+ self.call_method("_cache_support", args), [], [], body
+ ).set_lineno(lineno)
+
+ def _cache_support(self, name, timeout, caller):
+ """Helper callback."""
+ key = self.environment.fragment_cache_prefix + name
+
+ # try to load the block from the cache
+ # if there is no fragment in the cache, render it and store
+ # it in the cache.
+ rv = self.environment.fragment_cache.get(key)
+ if rv is not None:
+ return rv
+ rv = caller()
+ self.environment.fragment_cache.add(key, rv, timeout)
+ return rv
diff --git a/docs/examples/inline_gettext_extension.py b/docs/examples/inline_gettext_extension.py
new file mode 100644
index 0000000..bf8b9db
--- /dev/null
+++ b/docs/examples/inline_gettext_extension.py
@@ -0,0 +1,72 @@
+import re
+
+from jinja2.exceptions import TemplateSyntaxError
+from jinja2.ext import Extension
+from jinja2.lexer import count_newlines
+from jinja2.lexer import Token
+
+
+_outside_re = re.compile(r"\\?(gettext|_)\(")
+_inside_re = re.compile(r"\\?[()]")
+
+
+class InlineGettext(Extension):
+ """This extension implements support for inline gettext blocks::
+
+ <h1>_(Welcome)</h1>
+ <p>_(This is a paragraph)</p>
+
+ Requires the i18n extension to be loaded and configured.
+ """
+
+ def filter_stream(self, stream):
+ paren_stack = 0
+
+ for token in stream:
+ if token.type != "data":
+ yield token
+ continue
+
+ pos = 0
+ lineno = token.lineno
+
+ while True:
+ if not paren_stack:
+ match = _outside_re.search(token.value, pos)
+ else:
+ match = _inside_re.search(token.value, pos)
+ if match is None:
+ break
+ new_pos = match.start()
+ if new_pos > pos:
+ preval = token.value[pos:new_pos]
+ yield Token(lineno, "data", preval)
+ lineno += count_newlines(preval)
+ gtok = match.group()
+ if gtok[0] == "\\":
+ yield Token(lineno, "data", gtok[1:])
+ elif not paren_stack:
+ yield Token(lineno, "block_begin", None)
+ yield Token(lineno, "name", "trans")
+ yield Token(lineno, "block_end", None)
+ paren_stack = 1
+ else:
+ if gtok == "(" or paren_stack > 1:
+ yield Token(lineno, "data", gtok)
+ paren_stack += -1 if gtok == ")" else 1
+ if not paren_stack:
+ yield Token(lineno, "block_begin", None)
+ yield Token(lineno, "name", "endtrans")
+ yield Token(lineno, "block_end", None)
+ pos = match.end()
+
+ if pos < len(token.value):
+ yield Token(lineno, "data", token.value[pos:])
+
+ if paren_stack:
+ raise TemplateSyntaxError(
+ "unclosed gettext expression",
+ token.lineno,
+ stream.name,
+ stream.filename,
+ )
diff --git a/docs/extensions.rst b/docs/extensions.rst
new file mode 100644
index 0000000..45ead3b
--- /dev/null
+++ b/docs/extensions.rst
@@ -0,0 +1,423 @@
+.. _jinja-extensions:
+
+Extensions
+==========
+
+Jinja supports extensions that can add extra filters, tests, globals or even
+extend the parser. The main motivation of extensions is to move often used
+code into a reusable class like adding support for internationalization.
+
+
+Adding Extensions
+-----------------
+
+Extensions are added to the Jinja environment at creation time. To add an
+extension pass a list of extension classes or import paths to the
+``extensions`` parameter of the :class:`~jinja2.Environment` constructor. The following
+example creates a Jinja environment with the i18n extension loaded::
+
+ jinja_env = Environment(extensions=['jinja2.ext.i18n'])
+
+To add extensions after creation time, use the :meth:`~jinja2.Environment.add_extension` method::
+
+ jinja_env.add_extension('jinja2.ext.debug')
+
+
+.. _i18n-extension:
+
+i18n Extension
+--------------
+
+**Import name:** ``jinja2.ext.i18n``
+
+The i18n extension can be used in combination with `gettext`_ or
+`Babel`_. When it's enabled, Jinja provides a ``trans`` statement that
+marks a block as translatable and calls ``gettext``.
+
+After enabling, an application has to provide functions for ``gettext``,
+``ngettext``, and optionally ``pgettext`` and ``npgettext``, either
+globally or when rendering. A ``_()`` function is added as an alias to
+the ``gettext`` function.
+
+
+Environment Methods
+~~~~~~~~~~~~~~~~~~~
+
+After enabling the extension, the environment provides the following
+additional methods:
+
+.. method:: jinja2.Environment.install_gettext_translations(translations, newstyle=False)
+
+ Installs a translation globally for the environment. The
+ ``translations`` object must implement ``gettext``, ``ngettext``,
+ and optionally ``pgettext`` and ``npgettext``.
+ :class:`gettext.NullTranslations`, :class:`gettext.GNUTranslations`,
+ and `Babel`_\s ``Translations`` are supported.
+
+ .. versionchanged:: 3.0
+ Added ``pgettext`` and ``npgettext``.
+
+ .. versionchanged:: 2.5
+ Added new-style gettext support.
+
+.. method:: jinja2.Environment.install_null_translations(newstyle=False)
+
+ Install no-op gettext functions. This is useful if you want to
+ prepare the application for internationalization but don't want to
+ implement the full system yet.
+
+ .. versionchanged:: 2.5 Added new-style gettext support.
+
+.. method:: jinja2.Environment.install_gettext_callables(gettext, ngettext, newstyle=False, pgettext=None, npgettext=None)
+
+ Install the given ``gettext``, ``ngettext``, ``pgettext``, and
+ ``npgettext`` callables into the environment. They should behave
+ exactly like :func:`gettext.gettext`, :func:`gettext.ngettext`,
+ :func:`gettext.pgettext` and :func:`gettext.npgettext`.
+
+ If ``newstyle`` is activated, the callables are wrapped to work like
+ newstyle callables. See :ref:`newstyle-gettext` for more information.
+
+ .. versionchanged:: 3.0
+ Added ``pgettext`` and ``npgettext``.
+
+ .. versionadded:: 2.5
+ Added new-style gettext support.
+
+.. method:: jinja2.Environment.uninstall_gettext_translations()
+
+ Uninstall the environment's globally installed translation.
+
+.. method:: jinja2.Environment.extract_translations(source)
+
+ Extract localizable strings from the given template node or source.
+
+ For every string found this function yields a ``(lineno, function,
+ message)`` tuple, where:
+
+ - ``lineno`` is the number of the line on which the string was
+ found.
+ - ``function`` is the name of the ``gettext`` function used (if
+ the string was extracted from embedded Python code).
+ - ``message`` is the string itself, or a tuple of strings for
+ functions with multiple arguments.
+
+ If `Babel`_ is installed, see :ref:`babel-integration` to extract
+ the strings.
+
+For a web application that is available in multiple languages but gives
+all the users the same language (for example, multilingual forum
+software installed for a French community), the translation may be
+installed when the environment is created.
+
+.. code-block:: python
+
+ translations = get_gettext_translations()
+ env = Environment(extensions=["jinja2.ext.i18n"])
+ env.install_gettext_translations(translations)
+
+The ``get_gettext_translations`` function would return the translator
+for the current configuration, for example by using ``gettext.find``.
+
+The usage of the ``i18n`` extension for template designers is covered in
+:ref:`the template documentation <i18n-in-templates>`.
+
+.. _gettext: https://docs.python.org/3/library/gettext.html
+.. _Babel: https://babel.pocoo.org/
+
+
+Whitespace Trimming
+~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 2.10
+
+Within ``{% trans %}`` blocks, it can be useful to trim line breaks and
+whitespace so that the block of text looks like a simple string with
+single spaces in the translation file.
+
+Linebreaks and surrounding whitespace can be automatically trimmed by
+enabling the ``ext.i18n.trimmed`` :ref:`policy <ext-i18n-trimmed>`.
+
+
+.. _newstyle-gettext:
+
+New Style Gettext
+~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 2.5
+
+New style gettext calls are less to type, less error prone, and support
+autoescaping better.
+
+You can use "new style" gettext calls by setting
+``env.newstyle_gettext = True`` or passing ``newstyle=True`` to
+``env.install_translations``. They are fully supported by the Babel
+extraction tool, but might not work as expected with other extraction
+tools.
+
+With standard ``gettext`` calls, string formatting is a separate step
+done with the ``|format`` filter. This requires duplicating work for
+``ngettext`` calls.
+
+.. sourcecode:: jinja
+
+ {{ gettext("Hello, World!") }}
+ {{ gettext("Hello, %(name)s!")|format(name=name) }}
+ {{ ngettext(
+ "%(num)d apple", "%(num)d apples", apples|count
+ )|format(num=apples|count) }}
+ {{ pgettext("greeting", "Hello, World!") }}
+ {{ npgettext(
+ "fruit", "%(num)d apple", "%(num)d apples", apples|count
+ )|format(num=apples|count) }}
+
+New style ``gettext`` make formatting part of the call, and behind the
+scenes enforce more consistency.
+
+.. sourcecode:: jinja
+
+ {{ gettext("Hello, World!") }}
+ {{ gettext("Hello, %(name)s!", name=name) }}
+ {{ ngettext("%(num)d apple", "%(num)d apples", apples|count) }}
+ {{ pgettext("greeting", "Hello, World!") }}
+ {{ npgettext("fruit", "%(num)d apple", "%(num)d apples", apples|count) }}
+
+The advantages of newstyle gettext are:
+
+- There's no separate formatting step, you don't have to remember to
+ use the ``|format`` filter.
+- Only named placeholders are allowed. This solves a common problem
+ translators face because positional placeholders can't switch
+ positions meaningfully. Named placeholders always carry semantic
+ information about what value goes where.
+- String formatting is used even if no placeholders are used, which
+ makes all strings use a consistent format. Remember to escape any
+ raw percent signs as ``%%``, such as ``100%%``.
+- The translated string is marked safe, formatting performs escaping
+ as needed. Mark a parameter as ``|safe`` if it has already been
+ escaped.
+
+
+Expression Statement
+--------------------
+
+**Import name:** ``jinja2.ext.do``
+
+The "do" aka expression-statement extension adds a simple ``do`` tag to the
+template engine that works like a variable expression but ignores the
+return value.
+
+.. _loopcontrols-extension:
+
+Loop Controls
+-------------
+
+**Import name:** ``jinja2.ext.loopcontrols``
+
+This extension adds support for ``break`` and ``continue`` in loops. After
+enabling, Jinja provides those two keywords which work exactly like in
+Python.
+
+.. _with-extension:
+
+With Statement
+--------------
+
+**Import name:** ``jinja2.ext.with_``
+
+.. versionchanged:: 2.9
+
+ This extension is now built-in and no longer does anything.
+
+.. _autoescape-extension:
+
+Autoescape Extension
+--------------------
+
+**Import name:** ``jinja2.ext.autoescape``
+
+.. versionchanged:: 2.9
+
+ This extension was removed and is now built-in. Enabling the
+ extension no longer does anything.
+
+
+.. _debug-extension:
+
+Debug Extension
+---------------
+
+**Import name:** ``jinja2.ext.debug``
+
+Adds a ``{% debug %}`` tag to dump the current context as well as the
+available filters and tests. This is useful to see what's available to
+use in the template without setting up a debugger.
+
+
+.. _writing-extensions:
+
+Writing Extensions
+------------------
+
+.. module:: jinja2.ext
+
+By writing extensions you can add custom tags to Jinja. This is a non-trivial
+task and usually not needed as the default tags and expressions cover all
+common use cases. The i18n extension is a good example of why extensions are
+useful. Another one would be fragment caching.
+
+When writing extensions you have to keep in mind that you are working with the
+Jinja template compiler which does not validate the node tree you are passing
+to it. If the AST is malformed you will get all kinds of compiler or runtime
+errors that are horrible to debug. Always make sure you are using the nodes
+you create correctly. The API documentation below shows which nodes exist and
+how to use them.
+
+
+Example Extensions
+------------------
+
+Cache
+~~~~~
+
+The following example implements a ``cache`` tag for Jinja by using the
+`cachelib`_ library:
+
+.. literalinclude:: examples/cache_extension.py
+ :language: python
+
+And here is how you use it in an environment::
+
+ from jinja2 import Environment
+ from cachelib import SimpleCache
+
+ env = Environment(extensions=[FragmentCacheExtension])
+ env.fragment_cache = SimpleCache()
+
+Inside the template it's then possible to mark blocks as cacheable. The
+following example caches a sidebar for 300 seconds:
+
+.. sourcecode:: html+jinja
+
+ {% cache 'sidebar', 300 %}
+ <div class="sidebar">
+ ...
+ </div>
+ {% endcache %}
+
+.. _cachelib: https://github.com/pallets/cachelib
+
+
+Inline ``gettext``
+~~~~~~~~~~~~~~~~~~
+
+The following example demonstrates using :meth:`Extension.filter_stream`
+to parse calls to the ``_()`` gettext function inline with static data
+without needing Jinja blocks.
+
+.. code-block:: html
+
+ <h1>_(Welcome)</h1>
+ <p>_(This is a paragraph)</p>
+
+It requires the i18n extension to be loaded and configured.
+
+.. literalinclude:: examples/inline_gettext_extension.py
+ :language: python
+
+
+Extension API
+-------------
+
+Extension
+~~~~~~~~~
+
+Extensions always have to extend the :class:`jinja2.ext.Extension` class:
+
+.. autoclass:: Extension
+ :members: preprocess, filter_stream, parse, attr, call_method
+
+ .. attribute:: identifier
+
+ The identifier of the extension. This is always the true import name
+ of the extension class and must not be changed.
+
+ .. attribute:: tags
+
+ If the extension implements custom tags this is a set of tag names
+ the extension is listening for.
+
+
+Parser
+~~~~~~
+
+The parser passed to :meth:`Extension.parse` provides ways to parse
+expressions of different types. The following methods may be used by
+extensions:
+
+.. autoclass:: jinja2.parser.Parser
+ :members: parse_expression, parse_tuple, parse_assign_target,
+ parse_statements, free_identifier, fail
+
+ .. attribute:: filename
+
+ The filename of the template the parser processes. This is **not**
+ the load name of the template. For the load name see :attr:`name`.
+ For templates that were not loaded form the file system this is
+ ``None``.
+
+ .. attribute:: name
+
+ The load name of the template.
+
+ .. attribute:: stream
+
+ The current :class:`~jinja2.lexer.TokenStream`
+
+.. autoclass:: jinja2.lexer.TokenStream
+ :members: push, look, eos, skip, __next__, next_if, skip_if, expect
+
+ .. attribute:: current
+
+ The current :class:`~jinja2.lexer.Token`.
+
+.. autoclass:: jinja2.lexer.Token
+ :members: test, test_any
+
+ .. attribute:: lineno
+
+ The line number of the token
+
+ .. attribute:: type
+
+ The type of the token. This string is interned so you may compare
+ it with arbitrary strings using the ``is`` operator.
+
+ .. attribute:: value
+
+ The value of the token.
+
+There is also a utility function in the lexer module that can count newline
+characters in strings:
+
+.. autofunction:: jinja2.lexer.count_newlines
+
+
+AST
+~~~
+
+The AST (Abstract Syntax Tree) is used to represent a template after parsing.
+It's build of nodes that the compiler then converts into executable Python
+code objects. Extensions that provide custom statements can return nodes to
+execute custom Python code.
+
+The list below describes all nodes that are currently available. The AST may
+change between Jinja versions but will stay backwards compatible.
+
+For more information have a look at the repr of :meth:`jinja2.Environment.parse`.
+
+.. module:: jinja2.nodes
+
+.. jinja:nodes:: jinja2.nodes.Node
+
+.. autoexception:: Impossible
diff --git a/docs/faq.rst b/docs/faq.rst
new file mode 100644
index 0000000..493dc38
--- /dev/null
+++ b/docs/faq.rst
@@ -0,0 +1,75 @@
+Frequently Asked Questions
+==========================
+
+
+Why is it called Jinja?
+-----------------------
+
+"Jinja" is a Japanese `Shinto shrine`_, or temple, and temple and
+template share a similar English pronunciation. It is not named after
+the `city in Uganda`_.
+
+.. _Shinto shrine: https://en.wikipedia.org/wiki/Shinto_shrine
+.. _city in Uganda: https://en.wikipedia.org/wiki/Jinja%2C_Uganda
+
+
+How fast is Jinja?
+------------------
+
+Jinja is relatively fast among template engines because it compiles and
+caches template code to Python code, so that the template does not need
+to be parsed and interpreted each time. Rendering a template becomes as
+close to executing a Python function as possible.
+
+Jinja also makes extensive use of caching. Templates are cached by name
+after loading, so future uses of the template avoid loading. The
+template loading itself uses a bytecode cache to avoid repeated
+compiling. The caches can be external to persist across restarts.
+Templates can also be precompiled and loaded as fast Python imports.
+
+We dislike benchmarks because they don't reflect real use. Performance
+depends on many factors. Different engines have different default
+configurations and tradeoffs that make it unclear how to set up a useful
+comparison. Often, database access, API calls, and data processing have
+a much larger effect on performance than the template engine.
+
+
+Isn't it a bad idea to put logic in templates?
+----------------------------------------------
+
+Without a doubt you should try to remove as much logic from templates as
+possible. With less logic, the template is easier to understand, has
+fewer potential side effects, and is faster to compile and render. But a
+template without any logic means processing must be done in code before
+rendering. A template engine that does that is shipped with Python,
+called :class:`string.Template`, and while it's definitely fast it's not
+convenient.
+
+Jinja's features such as blocks, statements, filters, and function calls
+make it much easier to write expressive templates, with very few
+restrictions. Jinja doesn't allow arbitrary Python code in templates, or
+every feature available in the Python language. This keeps the engine
+easier to maintain, and keeps templates more readable.
+
+Some amount of logic is required in templates to keep everyone happy.
+Too much logic in the template can make it complex to reason about and
+maintain. It's up to you to decide how your application will work and
+balance how much logic you want to put in the template.
+
+
+Why is HTML escaping not the default?
+-------------------------------------
+
+Jinja provides a feature that can be enabled to escape HTML syntax in
+rendered templates. However, it is disabled by default.
+
+Jinja is a general purpose template engine, it is not only used for HTML
+documents. You can generate plain text, LaTeX, emails, CSS, JavaScript,
+configuration files, etc. HTML escaping wouldn't make sense for any of
+these document types.
+
+While automatic escaping means that you are less likely have an XSS
+problem, it also requires significant extra processing during compiling
+and rendering, which can reduce performance. Jinja uses MarkupSafe for
+escaping, which provides optimized C code for speed, but it still
+introduces overhead to track escaping across methods and formatting.
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..4ce2071
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,29 @@
+.. rst-class:: hide-header
+
+Jinja
+=====
+
+.. image:: _static/jinja-logo.png
+ :align: center
+ :target: https://palletsprojects.com/p/jinja/
+
+Jinja is a fast, expressive, extensible templating engine. Special
+placeholders in the template allow writing code similar to Python
+syntax. Then the template is passed data to render the final document.
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ intro
+ api
+ sandbox
+ nativetypes
+ templates
+ extensions
+ integration
+ switching
+ tricks
+ faq
+ license
+ changes
diff --git a/docs/integration.rst b/docs/integration.rst
new file mode 100644
index 0000000..b945fb3
--- /dev/null
+++ b/docs/integration.rst
@@ -0,0 +1,94 @@
+Integration
+===========
+
+
+Flask
+-----
+
+The `Flask`_ web application framework, also maintained by Pallets, uses
+Jinja templates by default. Flask sets up a Jinja environment and
+template loader for you, and provides functions to easily render
+templates from view functions.
+
+.. _Flask: https://flask.palletsprojects.com
+
+
+Django
+------
+
+Django supports using Jinja as its template engine, see
+https://docs.djangoproject.com/en/stable/topics/templates/#support-for-template-engines.
+
+
+.. _babel-integration:
+
+Babel
+-----
+
+Jinja provides support for extracting gettext messages from templates
+via a `Babel`_ extractor entry point called
+``jinja2.ext.babel_extract``. The support is implemented as part of the
+:ref:`i18n-extension` extension.
+
+Gettext messages are extracted from both ``trans`` tags and code
+expressions.
+
+To extract gettext messages from templates, the project needs a Jinja
+section in its Babel extraction method `mapping file`_:
+
+.. sourcecode:: ini
+
+ [jinja2: **/templates/**.html]
+ encoding = utf-8
+
+The syntax related options of the :class:`Environment` are also
+available as configuration values in the mapping file. For example, to
+tell the extractor that templates use ``%`` as
+``line_statement_prefix`` you can use this code:
+
+.. sourcecode:: ini
+
+ [jinja2: **/templates/**.html]
+ encoding = utf-8
+ line_statement_prefix = %
+
+:ref:`jinja-extensions` may also be defined by passing a comma separated
+list of import paths as the ``extensions`` value. The i18n extension is
+added automatically.
+
+Template syntax errors are ignored by default. The assumption is that
+tests will catch syntax errors in templates. If you don't want to ignore
+errors, add ``silent = false`` to the settings.
+
+.. _Babel: https://babel.readthedocs.io/
+.. _mapping file: https://babel.readthedocs.io/en/latest/messages.html#extraction-method-mapping-and-configuration
+
+
+Pylons
+------
+
+It's easy to integrate Jinja into a `Pylons`_ application.
+
+The template engine is configured in ``config/environment.py``. The
+configuration for Jinja looks something like this:
+
+.. code-block:: python
+
+ from jinja2 import Environment, PackageLoader
+ config['pylons.app_globals'].jinja_env = Environment(
+ loader=PackageLoader('yourapplication', 'templates')
+ )
+
+After that you can render Jinja templates by using the ``render_jinja``
+function from the ``pylons.templating`` module.
+
+Additionally it's a good idea to set the Pylons ``c`` object to strict
+mode. By default attribute access on missing attributes on the ``c``
+object returns an empty string and not an undefined object. To change
+this add this to ``config/environment.py``:
+
+.. code-block:: python
+
+ config['pylons.strict_c'] = True
+
+.. _Pylons: https://pylonshq.com/
diff --git a/docs/intro.rst b/docs/intro.rst
new file mode 100644
index 0000000..fd6f84f
--- /dev/null
+++ b/docs/intro.rst
@@ -0,0 +1,63 @@
+Introduction
+============
+
+Jinja is a fast, expressive, extensible templating engine. Special
+placeholders in the template allow writing code similar to Python
+syntax. Then the template is passed data to render the final document.
+
+It includes:
+
+- Template inheritance and inclusion.
+- Define and import macros within templates.
+- HTML templates can use autoescaping to prevent XSS from untrusted
+ user input.
+- A sandboxed environment can safely render untrusted templates.
+- Async support for generating templates that automatically handle
+ sync and async functions without extra syntax.
+- I18N support with Babel.
+- Templates are compiled to optimized Python code just-in-time and
+ cached, or can be compiled ahead-of-time.
+- Exceptions point to the correct line in templates to make debugging
+ easier.
+- Extensible filters, tests, functions, and even syntax.
+
+Jinja's philosophy is that while application logic belongs in Python if
+possible, it shouldn't make the template designer's job difficult by
+restricting functionality too much.
+
+
+Installation
+------------
+
+We recommend using the latest version of Python. Jinja supports Python
+3.7 and newer. We also recommend using a `virtual environment`_ in order
+to isolate your project dependencies from other projects and the system.
+
+.. _virtual environment: https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments
+
+Install the most recent Jinja version using pip:
+
+.. code-block:: text
+
+ $ pip install Jinja2
+
+
+Dependencies
+~~~~~~~~~~~~
+
+These will be installed automatically when installing Jinja.
+
+- `MarkupSafe`_ escapes untrusted input when rendering templates to
+ avoid injection attacks.
+
+.. _MarkupSafe: https://markupsafe.palletsprojects.com/
+
+
+Optional Dependencies
+~~~~~~~~~~~~~~~~~~~~~
+
+These distributions will not be installed automatically.
+
+- `Babel`_ provides translation support in templates.
+
+.. _Babel: https://babel.pocoo.org/
diff --git a/docs/license.rst b/docs/license.rst
new file mode 100644
index 0000000..a53a98c
--- /dev/null
+++ b/docs/license.rst
@@ -0,0 +1,4 @@
+BSD-3-Clause License
+====================
+
+.. include:: ../LICENSE.rst
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..b162255
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.https://www.sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
diff --git a/docs/nativetypes.rst b/docs/nativetypes.rst
new file mode 100644
index 0000000..1a08700
--- /dev/null
+++ b/docs/nativetypes.rst
@@ -0,0 +1,64 @@
+.. module:: jinja2.nativetypes
+
+.. _nativetypes:
+
+Native Python Types
+===================
+
+The default :class:`~jinja2.Environment` renders templates to strings. With
+:class:`NativeEnvironment`, rendering a template produces a native Python type.
+This is useful if you are using Jinja outside the context of creating text
+files. For example, your code may have an intermediate step where users may use
+templates to define values that will then be passed to a traditional string
+environment.
+
+Examples
+--------
+
+Adding two values results in an integer, not a string with a number:
+
+>>> env = NativeEnvironment()
+>>> t = env.from_string('{{ x + y }}')
+>>> result = t.render(x=4, y=2)
+>>> print(result)
+6
+>>> print(type(result))
+int
+
+Rendering list syntax produces a list:
+
+>>> t = env.from_string('[{% for item in data %}{{ item + 1 }},{% endfor %}]')
+>>> result = t.render(data=range(5))
+>>> print(result)
+[1, 2, 3, 4, 5]
+>>> print(type(result))
+list
+
+Rendering something that doesn't look like a Python literal produces a string:
+
+>>> t = env.from_string('{{ x }} * {{ y }}')
+>>> result = t.render(x=4, y=2)
+>>> print(result)
+4 * 2
+>>> print(type(result))
+str
+
+Rendering a Python object produces that object as long as it is the only node:
+
+>>> class Foo:
+... def __init__(self, value):
+... self.value = value
+...
+>>> result = env.from_string('{{ x }}').render(x=Foo(15))
+>>> print(type(result).__name__)
+Foo
+>>> print(result.value)
+15
+
+API
+---
+
+.. autoclass:: NativeEnvironment([options])
+
+.. autoclass:: NativeTemplate([options])
+ :members: render
diff --git a/docs/sandbox.rst b/docs/sandbox.rst
new file mode 100644
index 0000000..fc9c31f
--- /dev/null
+++ b/docs/sandbox.rst
@@ -0,0 +1,111 @@
+Sandbox
+=======
+
+The Jinja sandbox can be used to render untrusted templates. Access to
+attributes, method calls, operators, mutating data structures, and
+string formatting can be intercepted and prohibited.
+
+.. code-block:: pycon
+
+ >>> from jinja2.sandbox import SandboxedEnvironment
+ >>> env = SandboxedEnvironment()
+ >>> func = lambda: "Hello, Sandbox!"
+ >>> env.from_string("{{ func() }}").render(func=func)
+ 'Hello, Sandbox!'
+ >>> env.from_string("{{ func.__code__.co_code }}").render(func=func)
+ Traceback (most recent call last):
+ ...
+ SecurityError: access to attribute '__code__' of 'function' object is unsafe.
+
+A sandboxed environment can be useful, for example, to allow users of an
+internal reporting system to create custom emails. You would document
+what data is available in the templates, then the user would write a
+template using that information. Your code would generate the report
+data and pass it to the user's sandboxed template to render.
+
+
+Security Considerations
+-----------------------
+
+The sandbox alone is not a solution for perfect security. Keep these
+things in mind when using the sandbox.
+
+Templates can still raise errors when compiled or rendered. Your code
+should attempt to catch errors instead of crashing.
+
+It is possible to construct a relatively small template that renders to
+a very large amount of output, which could correspond to a high use of
+CPU or memory. You should run your application with limits on resources
+such as CPU and memory to mitigate this.
+
+Jinja only renders text, it does not understand, for example, JavaScript
+code. Depending on how the rendered template will be used, you may need
+to do other postprocessing to restrict the output.
+
+Pass only the data that is relevant to the template. Avoid passing
+global data, or objects with methods that have side effects. By default
+the sandbox prevents private and internal attribute access. You can
+override :meth:`~SandboxedEnvironment.is_safe_attribute` to further
+restrict attributes access. Decorate methods with :func:`unsafe` to
+prevent calling them from templates when passing objects as data. Use
+:class:`ImmutableSandboxedEnvironment` to prevent modifying lists and
+dictionaries.
+
+
+API
+---
+
+.. module:: jinja2.sandbox
+
+.. autoclass:: SandboxedEnvironment([options])
+ :members: is_safe_attribute, is_safe_callable, default_binop_table,
+ default_unop_table, intercepted_binops, intercepted_unops,
+ call_binop, call_unop
+
+.. autoclass:: ImmutableSandboxedEnvironment([options])
+
+.. autoexception:: SecurityError
+
+.. autofunction:: unsafe
+
+.. autofunction:: is_internal_attribute
+
+.. autofunction:: modifies_known_mutable
+
+
+Operator Intercepting
+---------------------
+
+For performance, Jinja outputs operators directly when compiling. This
+means it's not possible to intercept operator behavior by overriding
+:meth:`SandboxEnvironment.call <Environment.call>` by default, because
+operator special methods are handled by the Python interpreter, and
+might not correspond with exactly one method depending on the operator's
+use.
+
+The sandbox can instruct the compiler to output a function to intercept
+certain operators instead. Override
+:attr:`SandboxedEnvironment.intercepted_binops` and
+:attr:`SandboxedEnvironment.intercepted_unops` with the operator symbols
+you want to intercept. The compiler will replace the symbols with calls
+to :meth:`SandboxedEnvironment.call_binop` and
+:meth:`SandboxedEnvironment.call_unop` instead. The default
+implementation of those methods will use
+:attr:`SandboxedEnvironment.binop_table` and
+:attr:`SandboxedEnvironment.unop_table` to translate operator symbols
+into :mod:`operator` functions.
+
+For example, the power (``**``) operator can be disabled:
+
+.. code-block:: python
+
+ from jinja2.sandbox import SandboxedEnvironment
+
+ class MyEnvironment(SandboxedEnvironment):
+ intercepted_binops = frozenset(["**"])
+
+ def call_binop(self, context, operator, left, right):
+ if operator == "**":
+ return self.undefined("The power (**) operator is unavailable.")
+
+ return super().call_binop(self, context, operator, left, right)
diff --git a/docs/switching.rst b/docs/switching.rst
new file mode 100644
index 0000000..caa35c3
--- /dev/null
+++ b/docs/switching.rst
@@ -0,0 +1,181 @@
+Switching From Other Template Engines
+=====================================
+
+This is a brief guide on some of the differences between Jinja syntax
+and other template languages. See :doc:`/templates` for a comprehensive
+guide to Jinja syntax and features.
+
+
+Django
+------
+
+If you have previously worked with Django templates, you should find
+Jinja very familiar. Many of the syntax elements look and work the same.
+However, Jinja provides some more syntax elements, and some work a bit
+differently.
+
+This section covers the template changes. The API, including extension
+support, is fundamentally different so it won't be covered here.
+
+Django supports using Jinja as its template engine, see
+https://docs.djangoproject.com/en/stable/topics/templates/#support-for-template-engines.
+
+
+Method Calls
+~~~~~~~~~~~~
+
+In Django, methods are called implicitly, without parentheses.
+
+.. code-block:: django
+
+ {% for page in user.get_created_pages %}
+ ...
+ {% endfor %}
+
+In Jinja, using parentheses is required for calls, like in Python. This
+allows you to pass variables to the method, which is not possible
+in Django. This syntax is also used for calling macros.
+
+.. code-block:: jinja
+
+ {% for page in user.get_created_pages() %}
+ ...
+ {% endfor %}
+
+
+Filter Arguments
+~~~~~~~~~~~~~~~~
+
+In Django, one literal value can be passed to a filter after a colon.
+
+.. code-block:: django
+
+ {{ items|join:", " }}
+
+In Jinja, filters can take any number of positional and keyword
+arguments in parentheses, like function calls. Arguments can also be
+variables instead of literal values.
+
+.. code-block:: jinja
+
+ {{ items|join(", ") }}
+
+
+Tests
+~~~~~
+
+In addition to filters, Jinja also has "tests" used with the ``is``
+operator. This operator is not the same as the Python operator.
+
+.. code-block:: jinja
+
+ {% if user.user_id is odd %}
+ {{ user.username|e }} is odd
+ {% else %}
+ hmm. {{ user.username|e }} looks pretty normal
+ {% endif %}
+
+Loops
+~~~~~
+
+In Django, the special variable for the loop context is called
+``forloop``, and the ``empty`` is used for no loop items.
+
+.. code-block:: django
+
+ {% for item in items %}
+ {{ item }}
+ {% empty %}
+ No items!
+ {% endfor %}
+
+In Jinja, the special variable for the loop context is called ``loop``,
+and the ``else`` block is used for no loop items.
+
+.. code-block:: jinja
+
+ {% for item in items %}
+ {{ loop.index}}. {{ item }}
+ {% else %}
+ No items!
+ {% endfor %}
+
+
+Cycle
+~~~~~
+
+In Django, the ``{% cycle %}`` can be used in a for loop to alternate
+between values per loop.
+
+.. code-block:: django
+
+ {% for user in users %}
+ <li class="{% cycle 'odd' 'even' %}">{{ user }}</li>
+ {% endfor %}
+
+In Jinja, the ``loop`` context has a ``cycle`` method.
+
+.. code-block:: jinja
+
+ {% for user in users %}
+ <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
+ {% endfor %}
+
+A cycler can also be assigned to a variable and used outside or across
+loops with the ``cycle()`` global function.
+
+
+Mako
+----
+
+You can configure Jinja to look more like Mako:
+
+.. code-block:: python
+
+ env = Environment(
+ block_start_string="<%",
+ block_end_string="%>",
+ variable_start_string="${",
+ variable_end_string="}",
+ comment_start_string="<%doc>",
+ commend_end_string="</%doc>",
+ line_statement_prefix="%",
+ line_comment_prefix="##",
+ )
+
+With an environment configured like that, Jinja should be able to
+interpret a small subset of Mako templates without any changes.
+
+Jinja does not support embedded Python code, so you would have to move
+that out of the template. You could either process the data with the
+same code before rendering, or add a global function or filter to the
+Jinja environment.
+
+The syntax for defs (which are called macros in Jinja) and template
+inheritance is different too.
+
+The following Mako template:
+
+.. code-block:: mako
+
+ <%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:
+
+.. code-block:: jinja
+
+ <% extends "layout.html" %>
+ <% block title %>Page Title<% endblock %>
+ <% block body %>
+ <ul>
+ % for item in list:
+ <li>${item}</li>
+ % endfor
+ </ul>
+ <% endblock %>
diff --git a/docs/templates.rst b/docs/templates.rst
new file mode 100644
index 0000000..7a64750
--- /dev/null
+++ b/docs/templates.rst
@@ -0,0 +1,1949 @@
+.. py:currentmodule:: jinja2
+.. highlight:: html+jinja
+
+Template Designer Documentation
+===============================
+
+This document describes the syntax and semantics of the template engine and
+will be most useful as reference to those creating Jinja templates. As the
+template engine is very flexible, the configuration from the application can
+be slightly different from the code presented here in terms of delimiters and
+behavior of undefined values.
+
+
+Synopsis
+--------
+
+A Jinja template is simply a text file. Jinja can generate any text-based
+format (HTML, XML, CSV, LaTeX, etc.). A Jinja template doesn't need to have a
+specific extension: ``.html``, ``.xml``, or any other extension is just fine.
+
+A template contains **variables** and/or **expressions**, which get replaced
+with values when a template is *rendered*; and **tags**, which control the
+logic of the template. The template syntax is heavily inspired by Django and
+Python.
+
+Below is a minimal template that illustrates a few basics using the default
+Jinja configuration. We will cover the details later in this document::
+
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <title>My Webpage</title>
+ </head>
+ <body>
+ <ul id="navigation">
+ {% for item in navigation %}
+ <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
+ {% endfor %}
+ </ul>
+
+ <h1>My Webpage</h1>
+ {{ a_variable }}
+
+ {# a comment #}
+ </body>
+ </html>
+
+The following example shows the default configuration settings. An application
+developer can change the syntax configuration from ``{% foo %}`` to ``<% foo
+%>``, or something similar.
+
+There are a few kinds of delimiters. The default Jinja delimiters are
+configured as follows:
+
+* ``{% ... %}`` for :ref:`Statements <list-of-control-structures>`
+* ``{{ ... }}`` for :ref:`Expressions` to print to the template output
+* ``{# ... #}`` for :ref:`Comments` not included in the template output
+
+:ref:`Line Statements and Comments <line-statements>` are also possible,
+though they don't have default prefix characters. To use them, set
+``line_statement_prefix`` and ``line_comment_prefix`` when creating the
+:class:`~jinja2.Environment`.
+
+
+Template File Extension
+~~~~~~~~~~~~~~~~~~~~~~~
+
+As stated above, any file can be loaded as a template, regardless of
+file extension. Adding a ``.jinja`` extension, like ``user.html.jinja``
+may make it easier for some IDEs or editor plugins, but is not required.
+Autoescaping, introduced later, can be applied based on file extension,
+so you'll need to take the extra suffix into account in that case.
+
+Another good heuristic for identifying templates is that they are in a
+``templates`` folder, regardless of extension. This is a common layout
+for projects.
+
+
+.. _variables:
+
+Variables
+---------
+
+Template variables are defined by the context dictionary passed to the
+template.
+
+You can mess around with the variables in templates provided they are passed in
+by the application. Variables may have attributes or elements on them you can
+access too. What attributes a variable has depends heavily on the application
+providing that variable.
+
+You can use a dot (``.``) to access attributes of a variable in addition
+to the standard Python ``__getitem__`` "subscript" syntax (``[]``).
+
+The following lines do the same thing::
+
+ {{ foo.bar }}
+ {{ foo['bar'] }}
+
+It's important to know that the outer double-curly braces are *not* part of the
+variable, but the print statement. If you access variables inside tags don't
+put the braces around them.
+
+If a variable or attribute does not exist, you will get back an undefined
+value. What you can do with that kind of value depends on the application
+configuration: the default behavior is to evaluate to an empty string if
+printed or iterated over, and to fail for every other operation.
+
+.. _notes-on-subscriptions:
+
+.. admonition:: Implementation
+
+ For the sake of convenience, ``foo.bar`` in Jinja does the following
+ things on the Python layer:
+
+ - check for an attribute called `bar` on `foo`
+ (``getattr(foo, 'bar')``)
+ - if there is not, check for an item ``'bar'`` in `foo`
+ (``foo.__getitem__('bar')``)
+ - if there is not, return an undefined object.
+
+ ``foo['bar']`` works mostly the same with a small difference in sequence:
+
+ - check for an item ``'bar'`` in `foo`.
+ (``foo.__getitem__('bar')``)
+ - if there is not, check for an attribute called `bar` on `foo`.
+ (``getattr(foo, 'bar')``)
+ - if there is not, return an undefined object.
+
+ This is important if an object has an item and attribute with the same
+ name. Additionally, the :func:`attr` filter only looks up attributes.
+
+.. _filters:
+
+Filters
+-------
+
+Variables can be modified by **filters**. Filters are separated from the
+variable by a pipe symbol (``|``) and may have optional arguments in
+parentheses. Multiple filters can be chained. The output of one filter is
+applied to the next.
+
+For example, ``{{ name|striptags|title }}`` will remove all HTML Tags from
+variable `name` and title-case the output (``title(striptags(name))``).
+
+Filters that accept arguments have parentheses around the arguments, just like
+a function call. For example: ``{{ listx|join(', ') }}`` will join a list with
+commas (``str.join(', ', listx)``).
+
+The :ref:`builtin-filters` below describes all the builtin filters.
+
+.. _tests:
+
+Tests
+-----
+
+Beside filters, there are also so-called "tests" available. Tests can be used
+to test a variable against a common expression. To test a variable or
+expression, you add `is` plus the name of the test after the variable. For
+example, to find out if a variable is defined, you can do ``name is defined``,
+which will then return true or false depending on whether `name` is defined
+in the current template context.
+
+Tests can accept arguments, too. If the test only takes one argument, you can
+leave out the parentheses. For example, the following two
+expressions do the same thing::
+
+ {% if loop.index is divisibleby 3 %}
+ {% if loop.index is divisibleby(3) %}
+
+The :ref:`builtin-tests` below describes all the builtin tests.
+
+
+.. _comments:
+
+Comments
+--------
+
+To comment-out part of a line in a template, use the comment syntax which is
+by default set to ``{# ... #}``. This is useful to comment out parts of the
+template for debugging or to add information for other template designers or
+yourself::
+
+ {# note: commented-out template because we no longer use this
+ {% for user in users %}
+ ...
+ {% endfor %}
+ #}
+
+
+Whitespace Control
+------------------
+
+In the default configuration:
+
+* a single trailing newline is stripped if present
+* other whitespace (spaces, tabs, newlines etc.) is returned unchanged
+
+If an application configures Jinja to `trim_blocks`, the first newline after a
+template tag is removed automatically (like in PHP). The `lstrip_blocks`
+option can also be set to strip tabs and spaces from the beginning of a
+line to the start of a block. (Nothing will be stripped if there are
+other characters before the start of the block.)
+
+With both `trim_blocks` and `lstrip_blocks` enabled, you can put block tags
+on their own lines, and the entire block line will be removed when
+rendered, preserving the whitespace of the contents. For example,
+without the `trim_blocks` and `lstrip_blocks` options, this template::
+
+ <div>
+ {% if True %}
+ yay
+ {% endif %}
+ </div>
+
+gets rendered with blank lines inside the div::
+
+ <div>
+
+ yay
+
+ </div>
+
+But with both `trim_blocks` and `lstrip_blocks` enabled, the template block
+lines are removed and other whitespace is preserved::
+
+ <div>
+ yay
+ </div>
+
+You can manually disable the `lstrip_blocks` behavior by putting a
+plus sign (``+``) at the start of a block::
+
+ <div>
+ {%+ if something %}yay{% endif %}
+ </div>
+
+Similarly, you can manually disable the ``trim_blocks`` behavior by
+putting a plus sign (``+``) at the end of a block::
+
+ <div>
+ {% if something +%}
+ yay
+ {% endif %}
+ </div>
+
+You can also strip whitespace in templates by hand. If you add a minus
+sign (``-``) to the start or end of a block (e.g. a :ref:`for-loop` tag), a
+comment, or a variable expression, the whitespaces before or after
+that block will be removed::
+
+ {% for item in seq -%}
+ {{ item }}
+ {%- endfor %}
+
+This will yield all elements without whitespace between them. If `seq` was
+a list of numbers from ``1`` to ``9``, the output would be ``123456789``.
+
+If :ref:`line-statements` are enabled, they strip leading whitespace
+automatically up to the beginning of the line.
+
+By default, Jinja also removes trailing newlines. To keep single
+trailing newlines, configure Jinja to `keep_trailing_newline`.
+
+.. admonition:: Note
+
+ You must not add whitespace between the tag and the minus sign.
+
+ **valid**::
+
+ {%- if foo -%}...{% endif %}
+
+ **invalid**::
+
+ {% - if foo - %}...{% endif %}
+
+
+Escaping
+--------
+
+It is sometimes desirable -- even necessary -- to have Jinja ignore parts
+it would otherwise handle as variables or blocks. For example, if, with
+the default syntax, you want to use ``{{`` as a raw string in a template and
+not start a variable, you have to use a trick.
+
+The easiest way to output a literal variable delimiter (``{{``) is by using a
+variable expression::
+
+ {{ '{{' }}
+
+For bigger sections, it makes sense to mark a block `raw`. For example, to
+include example Jinja syntax in a template, you can use this snippet::
+
+ {% raw %}
+ <ul>
+ {% for item in seq %}
+ <li>{{ item }}</li>
+ {% endfor %}
+ </ul>
+ {% endraw %}
+
+.. admonition:: Note
+
+ Minus sign at the end of ``{% raw -%}`` tag cleans all the spaces and newlines
+ preceding the first character of your raw data.
+
+
+.. _line-statements:
+
+Line Statements
+---------------
+
+If line statements are enabled by the application, it's possible to mark a
+line as a statement. For example, if the line statement prefix is configured
+to ``#``, the following two examples are equivalent::
+
+ <ul>
+ # for item in seq
+ <li>{{ item }}</li>
+ # endfor
+ </ul>
+
+ <ul>
+ {% for item in seq %}
+ <li>{{ item }}</li>
+ {% endfor %}
+ </ul>
+
+The line statement prefix can appear anywhere on the line as long as no text
+precedes it. For better readability, statements that start a block (such as
+`for`, `if`, `elif` etc.) may end with a colon::
+
+ # for item in seq:
+ ...
+ # endfor
+
+
+.. admonition:: Note
+
+ Line statements can span multiple lines if there are open parentheses,
+ braces or brackets::
+
+ <ul>
+ # for href, caption in [('index.html', 'Index'),
+ ('about.html', 'About')]:
+ <li><a href="{{ href }}">{{ caption }}</a></li>
+ # endfor
+ </ul>
+
+Since Jinja 2.2, line-based comments are available as well. For example, if
+the line-comment prefix is configured to be ``##``, everything from ``##`` to
+the end of the line is ignored (excluding the newline sign)::
+
+ # for item in seq:
+ <li>{{ item }}</li> ## this comment is ignored
+ # endfor
+
+
+.. _template-inheritance:
+
+Template Inheritance
+--------------------
+
+The most powerful part of Jinja is template inheritance. Template inheritance
+allows you to build a base "skeleton" template that contains all the common
+elements of your site and defines **blocks** that child templates can override.
+
+Sounds complicated but is very basic. It's easiest to understand it by starting
+with an example.
+
+
+Base Template
+~~~~~~~~~~~~~
+
+This template, which we'll call ``base.html``, defines a simple HTML skeleton
+document that you might use for a simple two-column page. It's the job of
+"child" templates to fill the empty blocks with content::
+
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ {% block head %}
+ <link rel="stylesheet" href="style.css" />
+ <title>{% block title %}{% endblock %} - My Webpage</title>
+ {% endblock %}
+ </head>
+ <body>
+ <div id="content">{% block content %}{% endblock %}</div>
+ <div id="footer">
+ {% block footer %}
+ &copy; Copyright 2008 by <a href="http://domain.invalid/">you</a>.
+ {% endblock %}
+ </div>
+ </body>
+ </html>
+
+In this example, the ``{% block %}`` tags define four blocks that child templates
+can fill in. All the `block` tag does is tell the template engine that a
+child template may override those placeholders in the template.
+
+``block`` tags can be inside other blocks such as ``if``, but they will
+always be executed regardless of if the ``if`` block is actually
+rendered.
+
+Child Template
+~~~~~~~~~~~~~~
+
+A child template might look like this::
+
+ {% extends "base.html" %}
+ {% block title %}Index{% endblock %}
+ {% block head %}
+ {{ super() }}
+ <style type="text/css">
+ .important { color: #336699; }
+ </style>
+ {% endblock %}
+ {% block content %}
+ <h1>Index</h1>
+ <p class="important">
+ Welcome to my awesome homepage.
+ </p>
+ {% endblock %}
+
+The ``{% extends %}`` tag is the key here. It tells the template engine that
+this template "extends" another template. When the template system evaluates
+this template, it first locates the parent. The extends tag should be the
+first tag in the template. Everything before it is printed out normally and
+may cause confusion. For details about this behavior and how to take
+advantage of it, see :ref:`null-default-fallback`. Also a block will always be
+filled in regardless of whether the surrounding condition is evaluated to be true
+or false.
+
+The filename of the template depends on the template loader. For example, the
+:class:`FileSystemLoader` allows you to access other templates by giving the
+filename. You can access templates in subdirectories with a slash::
+
+ {% extends "layout/default.html" %}
+
+But this behavior can depend on the application embedding Jinja. Note that
+since the child template doesn't define the ``footer`` block, the value from
+the parent template is used instead.
+
+You can't define multiple ``{% block %}`` tags with the same name in the
+same template. This limitation exists because a block tag works in "both"
+directions. That is, a block tag doesn't just provide a placeholder to fill
+- it also defines the content that fills the placeholder in the *parent*.
+If there were two similarly-named ``{% block %}`` tags in a template,
+that template's parent wouldn't know which one of the blocks' content to use.
+
+If you want to print a block multiple times, you can, however, use the special
+`self` variable and call the block with that name::
+
+ <title>{% block title %}{% endblock %}</title>
+ <h1>{{ self.title() }}</h1>
+ {% block body %}{% endblock %}
+
+
+Super Blocks
+~~~~~~~~~~~~
+
+It's possible to render the contents of the parent block by calling ``super()``.
+This gives back the results of the parent block::
+
+ {% block sidebar %}
+ <h3>Table Of Contents</h3>
+ ...
+ {{ super() }}
+ {% endblock %}
+
+
+Nesting extends
+~~~~~~~~~~~~~~~
+
+In the case of multiple levels of ``{% extends %}``,
+``super`` references may be chained (as in ``super.super()``)
+to skip levels in the inheritance tree.
+
+For example::
+
+ # parent.tmpl
+ body: {% block body %}Hi from parent.{% endblock %}
+
+ # child.tmpl
+ {% extends "parent.tmpl" %}
+ {% block body %}Hi from child. {{ super() }}{% endblock %}
+
+ # grandchild1.tmpl
+ {% extends "child.tmpl" %}
+ {% block body %}Hi from grandchild1.{% endblock %}
+
+ # grandchild2.tmpl
+ {% extends "child.tmpl" %}
+ {% block body %}Hi from grandchild2. {{ super.super() }} {% endblock %}
+
+
+Rendering ``child.tmpl`` will give
+``body: Hi from child. Hi from parent.``
+
+Rendering ``grandchild1.tmpl`` will give
+``body: Hi from grandchild1.``
+
+Rendering ``grandchild2.tmpl`` will give
+``body: Hi from grandchild2. Hi from parent.``
+
+
+Named Block End-Tags
+~~~~~~~~~~~~~~~~~~~~
+
+Jinja allows you to put the name of the block after the end tag for better
+readability::
+
+ {% block sidebar %}
+ {% block inner_sidebar %}
+ ...
+ {% endblock inner_sidebar %}
+ {% endblock sidebar %}
+
+However, the name after the `endblock` word must match the block name.
+
+
+Block Nesting and Scope
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Blocks can be nested for more complex layouts. However, per default blocks
+may not access variables from outer scopes::
+
+ {% for item in seq %}
+ <li>{% block loop_item %}{{ item }}{% endblock %}</li>
+ {% endfor %}
+
+This example would output empty ``<li>`` items because `item` is unavailable
+inside the block. The reason for this is that if the block is replaced by
+a child template, a variable would appear that was not defined in the block or
+passed to the context.
+
+Starting with Jinja 2.2, you can explicitly specify that variables are
+available in a block by setting the block to "scoped" by adding the `scoped`
+modifier to a block declaration::
+
+ {% for item in seq %}
+ <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li>
+ {% endfor %}
+
+When overriding a block, the `scoped` modifier does not have to be provided.
+
+
+Required Blocks
+~~~~~~~~~~~~~~~
+
+Blocks can be marked as ``required``. They must be overridden at some
+point, but not necessarily by the direct child template. Required blocks
+may only contain space and comments, and they cannot be rendered
+directly.
+
+.. code-block:: jinja
+ :caption: ``page.txt``
+
+ {% block body required %}{% endblock %}
+
+.. code-block:: jinja
+ :caption: ``issue.txt``
+
+ {% extends "page.txt" %}
+
+.. code-block:: jinja
+ :caption: ``bug_report.txt``
+
+ {% extends "issue.txt" %}
+ {% block body %}Provide steps to demonstrate the bug.{% endblock %}
+
+Rendering ``page.txt`` or ``issue.txt`` will raise
+``TemplateRuntimeError`` because they don't override the ``body`` block.
+Rendering ``bug_report.txt`` will succeed because it does override the
+block.
+
+When combined with ``scoped``, the ``required`` modifier must be placed
+*after* the scoped modifier. Here are some valid examples:
+
+.. code-block:: jinja
+
+ {% block body scoped %}{% endblock %}
+ {% block body required %}{% endblock %}
+ {% block body scoped required %}{% endblock %}
+
+
+Template Objects
+~~~~~~~~~~~~~~~~
+
+``extends``, ``include``, and ``import`` can take a template object
+instead of the name of a template to load. This could be useful in some
+advanced situations, since you can use Python code to load a template
+first and pass it in to ``render``.
+
+.. code-block:: python
+
+ if debug_mode:
+ layout = env.get_template("debug_layout.html")
+ else:
+ layout = env.get_template("layout.html")
+
+ user_detail = env.get_template("user/detail.html", layout=layout)
+
+.. code-block:: jinja
+
+ {% extends layout %}
+
+Note how ``extends`` is passed the variable with the template object
+that was passed to ``render``, instead of a string.
+
+
+HTML Escaping
+-------------
+
+When generating HTML from templates, there's always a risk that a variable will
+include characters that affect the resulting HTML. There are two approaches:
+
+a. manually escaping each variable; or
+b. automatically escaping everything by default.
+
+Jinja supports both. What is used depends on the application configuration.
+The default configuration is no automatic escaping; for various reasons:
+
+- Escaping everything except for safe values will also mean that Jinja is
+ escaping variables known to not include HTML (e.g. numbers, booleans)
+ which can be a huge performance hit.
+
+- The information about the safety of a variable is very fragile. It could
+ happen that by coercing safe and unsafe values, the return value is
+ double-escaped HTML.
+
+Working with Manual Escaping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If manual escaping is enabled, it's **your** responsibility to escape
+variables if needed. What to escape? If you have a variable that *may*
+include any of the following chars (``>``, ``<``, ``&``, or ``"``) you
+**SHOULD** escape it unless the variable contains well-formed and trusted
+HTML. Escaping works by piping the variable through the ``|e`` filter::
+
+ {{ user.username|e }}
+
+Working with Automatic Escaping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When automatic escaping is enabled, everything is escaped by default except
+for values explicitly marked as safe. Variables and expressions
+can be marked as safe either in:
+
+a. The context dictionary by the application with
+ :class:`markupsafe.Markup`
+b. The template, with the ``|safe`` filter.
+
+If a string that you marked safe is passed through other Python code
+that doesn't understand that mark, it may get lost. Be aware of when
+your data is marked safe and how it is processed before arriving at the
+template.
+
+If a value has been escaped but is not marked safe, auto-escaping will
+still take place and result in double-escaped characters. If you know
+you have data that is already safe but not marked, be sure to wrap it in
+``Markup`` or use the ``|safe`` filter.
+
+Jinja functions (macros, `super`, `self.BLOCKNAME`) always return template
+data that is marked as safe.
+
+String literals in templates with automatic escaping are considered
+unsafe because native Python strings are not safe.
+
+.. _list-of-control-structures:
+
+List of Control Structures
+--------------------------
+
+A control structure refers to all those things that control the flow of a
+program - conditionals (i.e. if/elif/else), for-loops, as well as things like
+macros and blocks. With the default syntax, control structures appear inside
+``{% ... %}`` blocks.
+
+.. _for-loop:
+
+For
+~~~
+
+Loop over each item in a sequence. For example, to display a list of users
+provided in a variable called `users`::
+
+ <h1>Members</h1>
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+
+As variables in templates retain their object properties, it is possible to
+iterate over containers like `dict`::
+
+ <dl>
+ {% for key, value in my_dict.items() %}
+ <dt>{{ key|e }}</dt>
+ <dd>{{ value|e }}</dd>
+ {% endfor %}
+ </dl>
+
+Python dicts may not be in the order you want to display them in. If
+order matters, use the ``|dictsort`` filter.
+
+.. code-block:: jinja
+
+ <dl>
+ {% for key, value in my_dict | dictsort %}
+ <dt>{{ key|e }}</dt>
+ <dd>{{ value|e }}</dd>
+ {% endfor %}
+ </dl>
+
+Inside of a for-loop block, you can access some special variables:
+
++-----------------------+---------------------------------------------------+
+| Variable | Description |
++=======================+===================================================+
+| `loop.index` | The current iteration of the loop. (1 indexed) |
++-----------------------+---------------------------------------------------+
+| `loop.index0` | The current iteration of the loop. (0 indexed) |
++-----------------------+---------------------------------------------------+
+| `loop.revindex` | The number of iterations from the end of the loop |
+| | (1 indexed) |
++-----------------------+---------------------------------------------------+
+| `loop.revindex0` | The number of iterations from the end of the loop |
+| | (0 indexed) |
++-----------------------+---------------------------------------------------+
+| `loop.first` | True if first iteration. |
++-----------------------+---------------------------------------------------+
+| `loop.last` | True if last iteration. |
++-----------------------+---------------------------------------------------+
+| `loop.length` | The number of items in the sequence. |
++-----------------------+---------------------------------------------------+
+| `loop.cycle` | A helper function to cycle between a list of |
+| | sequences. See the explanation below. |
++-----------------------+---------------------------------------------------+
+| `loop.depth` | Indicates how deep in a recursive loop |
+| | the rendering currently is. Starts at level 1 |
++-----------------------+---------------------------------------------------+
+| `loop.depth0` | Indicates how deep in a recursive loop |
+| | the rendering currently is. Starts at level 0 |
++-----------------------+---------------------------------------------------+
+| `loop.previtem` | The item from the previous iteration of the loop. |
+| | Undefined during the first iteration. |
++-----------------------+---------------------------------------------------+
+| `loop.nextitem` | The item from the following iteration of the loop.|
+| | Undefined during the last iteration. |
++-----------------------+---------------------------------------------------+
+| `loop.changed(*val)` | True if previously called with a different value |
+| | (or not called at all). |
++-----------------------+---------------------------------------------------+
+
+Within a for-loop, it's possible to cycle among a list of strings/variables
+each time through the loop by using the special `loop.cycle` helper::
+
+ {% for row in rows %}
+ <li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li>
+ {% endfor %}
+
+Since Jinja 2.1, an extra `cycle` helper exists that allows loop-unbound
+cycling. For more information, have a look at the :ref:`builtin-globals`.
+
+.. _loop-filtering:
+
+Unlike in Python, it's not possible to `break` or `continue` in a loop. You
+can, however, filter the sequence during iteration, which allows you to skip
+items. The following example skips all the users which are hidden::
+
+ {% for user in users if not user.hidden %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+
+The advantage is that the special `loop` variable will count correctly; thus
+not counting the users not iterated over.
+
+If no iteration took place because the sequence was empty or the filtering
+removed all the items from the sequence, you can render a default block
+by using `else`::
+
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% else %}
+ <li><em>no users found</em></li>
+ {% endfor %}
+ </ul>
+
+Note that, in Python, `else` blocks are executed whenever the corresponding
+loop **did not** `break`. Since Jinja loops cannot `break` anyway,
+a slightly different behavior of the `else` keyword was chosen.
+
+It is also possible to use loops recursively. This is useful if you are
+dealing with recursive data such as sitemaps or RDFa.
+To use loops recursively, you basically have to add the `recursive` modifier
+to the loop definition and call the `loop` variable with the new iterable
+where you want to recurse.
+
+The following example implements a sitemap with recursive loops::
+
+ <ul class="sitemap">
+ {%- for item in sitemap recursive %}
+ <li><a href="{{ item.href|e }}">{{ item.title }}</a>
+ {%- if item.children -%}
+ <ul class="submenu">{{ loop(item.children) }}</ul>
+ {%- endif %}</li>
+ {%- endfor %}
+ </ul>
+
+The `loop` variable always refers to the closest (innermost) loop. If we
+have more than one level of loops, we can rebind the variable `loop` by
+writing `{% set outer_loop = loop %}` after the loop that we want to
+use recursively. Then, we can call it using `{{ outer_loop(...) }}`
+
+Please note that assignments in loops will be cleared at the end of the
+iteration and cannot outlive the loop scope. Older versions of Jinja had
+a bug where in some circumstances it appeared that assignments would work.
+This is not supported. See :ref:`assignments` for more information about
+how to deal with this.
+
+If all you want to do is check whether some value has changed since the
+last iteration or will change in the next iteration, you can use `previtem`
+and `nextitem`::
+
+ {% for value in values %}
+ {% if loop.previtem is defined and value > loop.previtem %}
+ The value just increased!
+ {% endif %}
+ {{ value }}
+ {% if loop.nextitem is defined and loop.nextitem > value %}
+ The value will increase even more!
+ {% endif %}
+ {% endfor %}
+
+If you only care whether the value changed at all, using `changed` is even
+easier::
+
+ {% for entry in entries %}
+ {% if loop.changed(entry.category) %}
+ <h2>{{ entry.category }}</h2>
+ {% endif %}
+ <p>{{ entry.message }}</p>
+ {% endfor %}
+
+.. _if:
+
+If
+~~
+
+The `if` statement in Jinja is comparable with the Python if statement.
+In the simplest form, you can use it to test if a variable is defined, not
+empty and not false::
+
+ {% if users %}
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username|e }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+For multiple branches, `elif` and `else` can be used like in Python. You can
+use more complex :ref:`expressions` there, too::
+
+ {% if kenny.sick %}
+ Kenny is sick.
+ {% elif kenny.dead %}
+ You killed Kenny! You bastard!!!
+ {% else %}
+ Kenny looks okay --- so far
+ {% endif %}
+
+If can also be used as an :ref:`inline expression <if-expression>` and for
+:ref:`loop filtering <loop-filtering>`.
+
+.. _macros:
+
+Macros
+~~~~~~
+
+Macros are comparable with functions in regular programming languages. They
+are useful to put often used idioms into reusable functions to not repeat
+yourself ("DRY").
+
+Here's a small example of a macro that renders a form element::
+
+ {% macro input(name, value='', type='text', size=20) -%}
+ <input type="{{ type }}" name="{{ name }}" value="{{
+ value|e }}" size="{{ size }}">
+ {%- endmacro %}
+
+The macro can then be called like a function in the namespace::
+
+ <p>{{ input('username') }}</p>
+ <p>{{ input('password', type='password') }}</p>
+
+If the macro was defined in a different template, you have to
+:ref:`import <import>` it first.
+
+Inside macros, you have access to three special variables:
+
+`varargs`
+ If more positional arguments are passed to the macro than accepted by the
+ macro, they end up in the special `varargs` variable as a list of values.
+
+`kwargs`
+ Like `varargs` but for keyword arguments. All unconsumed keyword
+ arguments are stored in this special variable.
+
+`caller`
+ If the macro was called from a :ref:`call<call>` tag, the caller is stored
+ in this variable as a callable macro.
+
+Macros also expose some of their internal details. The following attributes
+are available on a macro object:
+
+`name`
+ The name of the macro. ``{{ input.name }}`` will print ``input``.
+
+`arguments`
+ A tuple of the names of arguments the macro accepts.
+
+`catch_kwargs`
+ This is `true` if the macro accepts extra keyword arguments (i.e.: accesses
+ the special `kwargs` variable).
+
+`catch_varargs`
+ This is `true` if the macro accepts extra positional arguments (i.e.:
+ accesses the special `varargs` variable).
+
+`caller`
+ This is `true` if the macro accesses the special `caller` variable and may
+ be called from a :ref:`call<call>` tag.
+
+If a macro name starts with an underscore, it's not exported and can't
+be imported.
+
+Due to how scopes work in Jinja, a macro in a child template does not
+override a macro in a parent template. The following will output
+"LAYOUT", not "CHILD".
+
+.. code-block:: jinja
+ :caption: ``layout.txt``
+
+ {% macro foo() %}LAYOUT{% endmacro %}
+ {% block body %}{% endblock %}
+
+.. code-block:: jinja
+ :caption: ``child.txt``
+
+ {% extends 'layout.txt' %}
+ {% macro foo() %}CHILD{% endmacro %}
+ {% block body %}{{ foo() }}{% endblock %}
+
+
+.. _call:
+
+Call
+~~~~
+
+In some cases it can be useful to pass a macro to another macro. For this
+purpose, you can use the special `call` block. The following example shows
+a macro that takes advantage of the call functionality and how it can be
+used::
+
+ {% macro render_dialog(title, class='dialog') -%}
+ <div class="{{ class }}">
+ <h2>{{ title }}</h2>
+ <div class="contents">
+ {{ caller() }}
+ </div>
+ </div>
+ {%- endmacro %}
+
+ {% call render_dialog('Hello World') %}
+ This is a simple dialog rendered by using a macro and
+ a call block.
+ {% endcall %}
+
+It's also possible to pass arguments back to the call block. This makes it
+useful as a replacement for loops. Generally speaking, a call block works
+exactly like a macro without a name.
+
+Here's an example of how a call block can be used with arguments::
+
+ {% macro dump_users(users) -%}
+ <ul>
+ {%- for user in users %}
+ <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
+ {%- endfor %}
+ </ul>
+ {%- endmacro %}
+
+ {% call(user) dump_users(list_of_user) %}
+ <dl>
+ <dt>Realname</dt>
+ <dd>{{ user.realname|e }}</dd>
+ <dt>Description</dt>
+ <dd>{{ user.description }}</dd>
+ </dl>
+ {% endcall %}
+
+
+Filters
+~~~~~~~
+
+Filter sections allow you to apply regular Jinja filters on a block of
+template data. Just wrap the code in the special `filter` section::
+
+ {% filter upper %}
+ This text becomes uppercase
+ {% endfilter %}
+
+
+.. _assignments:
+
+Assignments
+~~~~~~~~~~~
+
+Inside code blocks, you can also assign values to variables. Assignments at
+top level (outside of blocks, macros or loops) are exported from the template
+like top level macros and can be imported by other templates.
+
+Assignments use the `set` tag and can have multiple targets::
+
+ {% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
+ {% set key, value = call_something() %}
+
+.. admonition:: Scoping Behavior
+
+ Please keep in mind that it is not possible to set variables inside a
+ block and have them show up outside of it. This also applies to
+ loops. The only exception to that rule are if statements which do not
+ introduce a scope. As a result the following template is not going
+ to do what you might expect::
+
+ {% set iterated = false %}
+ {% for item in seq %}
+ {{ item }}
+ {% set iterated = true %}
+ {% endfor %}
+ {% if not iterated %} did not iterate {% endif %}
+
+ It is not possible with Jinja syntax to do this. Instead use
+ alternative constructs like the loop else block or the special `loop`
+ variable::
+
+ {% for item in seq %}
+ {{ item }}
+ {% else %}
+ did not iterate
+ {% endfor %}
+
+ As of version 2.10 more complex use cases can be handled using namespace
+ objects which allow propagating of changes across scopes::
+
+ {% set ns = namespace(found=false) %}
+ {% for item in items %}
+ {% if item.check_something() %}
+ {% set ns.found = true %}
+ {% endif %}
+ * {{ item.title }}
+ {% endfor %}
+ Found item having something: {{ ns.found }}
+
+ Note that the ``obj.attr`` notation in the `set` tag is only allowed for
+ namespace objects; attempting to assign an attribute on any other object
+ will raise an exception.
+
+ .. versionadded:: 2.10 Added support for namespace objects
+
+
+Block Assignments
+~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 2.8
+
+Starting with Jinja 2.8, it's possible to also use block assignments to
+capture the contents of a block into a variable name. This can be useful
+in some situations as an alternative for macros. In that case, instead of
+using an equals sign and a value, you just write the variable name and then
+everything until ``{% endset %}`` is captured.
+
+Example::
+
+ {% set navigation %}
+ <li><a href="/">Index</a>
+ <li><a href="/downloads">Downloads</a>
+ {% endset %}
+
+The `navigation` variable then contains the navigation HTML source.
+
+.. versionchanged:: 2.10
+
+Starting with Jinja 2.10, the block assignment supports filters.
+
+Example::
+
+ {% set reply | wordwrap %}
+ You wrote:
+ {{ message }}
+ {% endset %}
+
+
+.. _extends:
+
+Extends
+~~~~~~~
+
+The `extends` tag can be used to extend one template from another. You can
+have multiple `extends` tags in a file, but only one of them may be executed at
+a time.
+
+See the section about :ref:`template-inheritance` above.
+
+
+.. _blocks:
+
+Blocks
+~~~~~~
+
+Blocks are used for inheritance and act as both placeholders and replacements
+at the same time. They are documented in detail in the
+:ref:`template-inheritance` section.
+
+
+Include
+~~~~~~~
+
+The ``include`` tag renders another template and outputs the result into
+the current template.
+
+.. code-block:: jinja
+
+ {% include 'header.html' %}
+ Body goes here.
+ {% include 'footer.html' %}
+
+The included template has access to context of the current template by
+default. Use ``without context`` to use a separate context instead.
+``with context`` is also valid, but is the default behavior. See
+:ref:`import-visibility`.
+
+The included template can ``extend`` another template and override
+blocks in that template. However, the current template cannot override
+any blocks that the included template outputs.
+
+Use ``ignore missing`` to ignore the statement if the template does not
+exist. It must be placed *before* a context visibility statement.
+
+.. code-block:: jinja
+
+ {% include "sidebar.html" without context %}
+ {% include "sidebar.html" ignore missing %}
+ {% include "sidebar.html" ignore missing with context %}
+ {% include "sidebar.html" ignore missing without context %}
+
+If a list of templates is given, each will be tried in order until one
+is not missing. This can be used with ``ignore missing`` to ignore if
+none of the templates exist.
+
+.. code-block:: jinja
+
+ {% include ['page_detailed.html', 'page.html'] %}
+ {% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}
+
+A variable, with either a template name or template object, can also be
+passed to the statment.
+
+.. _import:
+
+Import
+~~~~~~
+
+Jinja supports putting often used code into macros. These macros can go into
+different templates and get imported from there. This works similarly to the
+import statements in Python. It's important to know that imports are cached
+and imported templates don't have access to the current template variables,
+just the globals by default. For more details about context behavior of
+imports and includes, see :ref:`import-visibility`.
+
+There are two ways to import templates. You can import a complete template
+into a variable or request specific macros / exported variables from it.
+
+Imagine we have a helper module that renders forms (called `forms.html`)::
+
+ {% macro input(name, value='', type='text') -%}
+ <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
+ {%- endmacro %}
+
+ {%- macro textarea(name, value='', rows=10, cols=40) -%}
+ <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols
+ }}">{{ value|e }}</textarea>
+ {%- endmacro %}
+
+The easiest and most flexible way to access a template's variables
+and macros is to import the whole template module into a variable.
+That way, you can access the attributes::
+
+ {% import 'forms.html' as forms %}
+ <dl>
+ <dt>Username</dt>
+ <dd>{{ forms.input('username') }}</dd>
+ <dt>Password</dt>
+ <dd>{{ forms.input('password', type='password') }}</dd>
+ </dl>
+ <p>{{ forms.textarea('comment') }}</p>
+
+
+Alternatively, you can import specific names from a template into the current
+namespace::
+
+ {% from 'forms.html' import input as input_field, textarea %}
+ <dl>
+ <dt>Username</dt>
+ <dd>{{ input_field('username') }}</dd>
+ <dt>Password</dt>
+ <dd>{{ input_field('password', type='password') }}</dd>
+ </dl>
+ <p>{{ textarea('comment') }}</p>
+
+Macros and variables starting with one or more underscores are private and
+cannot be imported.
+
+.. versionchanged:: 2.4
+ If a template object was passed to the template context, you can
+ import from that object.
+
+
+.. _import-visibility:
+
+Import Context Behavior
+-----------------------
+
+By default, included templates are passed the current context and imported
+templates are not. The reason for this is that imports, unlike includes,
+are cached; as imports are often used just as a module that holds macros.
+
+This behavior can be changed explicitly: by adding `with context`
+or `without context` to the import/include directive, the current context
+can be passed to the template and caching is disabled automatically.
+
+Here are two examples::
+
+ {% from 'forms.html' import input with context %}
+ {% include 'header.html' without context %}
+
+.. admonition:: Note
+
+ In Jinja 2.0, the context that was passed to the included template
+ did not include variables defined in the template. As a matter of
+ fact, this did not work::
+
+ {% for box in boxes %}
+ {% include "render_box.html" %}
+ {% endfor %}
+
+ The included template ``render_box.html`` is *not* able to access
+ `box` in Jinja 2.0. As of Jinja 2.1, ``render_box.html`` *is* able
+ to do so.
+
+
+.. _expressions:
+
+Expressions
+-----------
+
+Jinja allows basic expressions everywhere. These work very similarly to
+regular Python; even if you're not working with Python
+you should feel comfortable with it.
+
+Literals
+~~~~~~~~
+
+The simplest form of expressions are literals. Literals are representations
+for Python objects such as strings and numbers. The following literals exist:
+
+``"Hello World"``
+ Everything between two double or single quotes is a string. They are
+ useful whenever you need a string in the template (e.g. as
+ arguments to function calls and filters, or just to extend or include a
+ template).
+
+``42`` / ``123_456``
+ Integers are whole numbers without a decimal part. The '_' character
+ can be used to separate groups for legibility.
+
+``42.23`` / ``42.1e2`` / ``123_456.789``
+ Floating point numbers can be written using a '.' as a decimal mark.
+ They can also be written in scientific notation with an upper or
+ lower case 'e' to indicate the exponent part. The '_' character can
+ be used to separate groups for legibility, but cannot be used in the
+ exponent part.
+
+``['list', 'of', 'objects']``
+ Everything between two brackets is a list. Lists are useful for storing
+ sequential data to be iterated over. For example, you can easily
+ create a list of links using lists and tuples for (and with) a for loop::
+
+ <ul>
+ {% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
+ ('downloads.html', 'Downloads')] %}
+ <li><a href="{{ href }}">{{ caption }}</a></li>
+ {% endfor %}
+ </ul>
+
+``('tuple', 'of', 'values')``
+ Tuples are like lists that cannot be modified ("immutable"). If a tuple
+ only has one item, it must be followed by a comma (``('1-tuple',)``).
+ Tuples are usually used to represent items of two or more elements.
+ See the list example above for more details.
+
+``{'dict': 'of', 'key': 'and', 'value': 'pairs'}``
+ A dict in Python is a structure that combines keys and values. Keys must
+ be unique and always have exactly one value. Dicts are rarely used in
+ templates; they are useful in some rare cases such as the :func:`xmlattr`
+ filter.
+
+``true`` / ``false``
+ ``true`` is always true and ``false`` is always false.
+
+.. admonition:: Note
+
+ The special constants `true`, `false`, and `none` are indeed lowercase.
+ Because that caused confusion in the past, (`True` used to expand
+ to an undefined variable that was considered false),
+ all three can now also be written in title case
+ (`True`, `False`, and `None`).
+ However, for consistency, (all Jinja identifiers are lowercase)
+ you should use the lowercase versions.
+
+Math
+~~~~
+
+Jinja allows you to calculate with values. This is rarely useful in templates
+but exists for completeness' sake. The following operators are supported:
+
+``+``
+ Adds two objects together. Usually the objects are numbers, but if both are
+ strings or lists, you can concatenate them this way. This, however, is not
+ the preferred way to concatenate strings! For string concatenation, have
+ a look-see at the ``~`` operator. ``{{ 1 + 1 }}`` is ``2``.
+
+``-``
+ Subtract the second number from the first one. ``{{ 3 - 2 }}`` is ``1``.
+
+``/``
+ Divide two numbers. The return value will be a floating point number.
+ ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``.
+
+``//``
+ Divide two numbers and return the truncated integer result.
+ ``{{ 20 // 7 }}`` is ``2``.
+
+``%``
+ Calculate the remainder of an integer division. ``{{ 11 % 7 }}`` is ``4``.
+
+``*``
+ Multiply the left operand with the right one. ``{{ 2 * 2 }}`` would
+ return ``4``. This can also be used to repeat a string multiple times.
+ ``{{ '=' * 80 }}`` would print a bar of 80 equal signs.
+
+``**``
+ Raise the left operand to the power of the right operand.
+ ``{{ 2**3 }}`` would return ``8``.
+
+ Unlike Python, chained pow is evaluated left to right.
+ ``{{ 3**3**3 }}`` is evaluated as ``(3**3)**3`` in Jinja, but would
+ be evaluated as ``3**(3**3)`` in Python. Use parentheses in Jinja
+ to be explicit about what order you want. It is usually preferable
+ to do extended math in Python and pass the results to ``render``
+ rather than doing it in the template.
+
+ This behavior may be changed in the future to match Python, if it's
+ possible to introduce an upgrade path.
+
+
+Comparisons
+~~~~~~~~~~~
+
+``==``
+ Compares two objects for equality.
+
+``!=``
+ Compares two objects for inequality.
+
+``>``
+ ``true`` if the left hand side is greater than the right hand side.
+
+``>=``
+ ``true`` if the left hand side is greater or equal to the right hand side.
+
+``<``
+ ``true`` if the left hand side is lower than the right hand side.
+
+``<=``
+ ``true`` if the left hand side is lower or equal to the right hand side.
+
+Logic
+~~~~~
+
+For ``if`` statements, ``for`` filtering, and ``if`` expressions, it can be useful to
+combine multiple expressions:
+
+``and``
+ Return true if the left and the right operand are true.
+
+``or``
+ Return true if the left or the right operand are true.
+
+``not``
+ negate a statement (see below).
+
+``(expr)``
+ Parentheses group an expression.
+
+.. admonition:: Note
+
+ The ``is`` and ``in`` operators support negation using an infix notation,
+ too: ``foo is not bar`` and ``foo not in bar`` instead of ``not foo is bar``
+ and ``not foo in bar``. All other expressions require a prefix notation:
+ ``not (foo and bar).``
+
+
+Other Operators
+~~~~~~~~~~~~~~~
+
+The following operators are very useful but don't fit into any of the other
+two categories:
+
+``in``
+ Perform a sequence / mapping containment test. Returns true if the left
+ operand is contained in the right. ``{{ 1 in [1, 2, 3] }}`` would, for
+ example, return true.
+
+``is``
+ Performs a :ref:`test <tests>`.
+
+``|`` (pipe, vertical bar)
+ Applies a :ref:`filter <filters>`.
+
+``~`` (tilde)
+ Converts all operands into strings and concatenates them.
+
+ ``{{ "Hello " ~ name ~ "!" }}`` would return (assuming `name` is set
+ to ``'John'``) ``Hello John!``.
+
+``()``
+ Call a callable: ``{{ post.render() }}``. Inside of the parentheses you
+ can use positional arguments and keyword arguments like in Python:
+
+ ``{{ post.render(user, full=true) }}``.
+
+``.`` / ``[]``
+ Get an attribute of an object. (See :ref:`variables`)
+
+
+.. _if-expression:
+
+If Expression
+~~~~~~~~~~~~~
+
+It is also possible to use inline `if` expressions. These are useful in some
+situations. For example, you can use this to extend from one template if a
+variable is defined, otherwise from the default layout template::
+
+ {% extends layout_template if layout_template is defined else 'default.html' %}
+
+The general syntax is ``<do something> if <something is true> else <do
+something else>``.
+
+The `else` part is optional. If not provided, the else block implicitly
+evaluates into an :class:`Undefined` object (regardless of what ``undefined``
+in the environment is set to):
+
+.. code-block:: jinja
+
+ {{ "[{}]".format(page.title) if page.title }}
+
+
+.. _python-methods:
+
+Python Methods
+~~~~~~~~~~~~~~
+
+You can also use any of the methods defined on a variable's type.
+The value returned from the method invocation is used as the value of the expression.
+Here is an example that uses methods defined on strings (where ``page.title`` is a string):
+
+.. code-block:: text
+
+ {{ page.title.capitalize() }}
+
+This works for methods on user-defined types. For example, if variable
+``f`` of type ``Foo`` has a method ``bar`` defined on it, you can do the
+following:
+
+.. code-block:: text
+
+ {{ f.bar(value) }}
+
+Operator methods also work as expected. For example, ``%`` implements
+printf-style for strings:
+
+.. code-block:: text
+
+ {{ "Hello, %s!" % name }}
+
+Although you should prefer the ``.format`` method for that case (which
+is a bit contrived in the context of rendering a template):
+
+.. code-block:: text
+
+ {{ "Hello, {}!".format(name) }}
+
+
+.. _builtin-filters:
+
+List of Builtin Filters
+-----------------------
+
+.. py:currentmodule:: jinja-filters
+
+.. jinja:filters:: jinja2.defaults.DEFAULT_FILTERS
+
+
+.. _builtin-tests:
+
+List of Builtin Tests
+---------------------
+
+.. py:currentmodule:: jinja-tests
+
+.. jinja:tests:: jinja2.defaults.DEFAULT_TESTS
+
+
+.. _builtin-globals:
+
+List of Global Functions
+------------------------
+
+The following functions are available in the global scope by default:
+
+.. py:currentmodule:: jinja-globals
+
+.. function:: range([start,] stop[, step])
+
+ Return a list containing an arithmetic progression of integers.
+ ``range(i, j)`` returns ``[i, i+1, i+2, ..., j-1]``;
+ start (!) defaults to ``0``.
+ When step is given, it specifies the increment (or decrement).
+ For example, ``range(4)`` and ``range(0, 4, 1)`` return ``[0, 1, 2, 3]``.
+ The end point is omitted!
+ These are exactly the valid indices for a list of 4 elements.
+
+ This is useful to repeat a template block multiple times, e.g.
+ to fill a list. Imagine you have 7 users in the list but you want to
+ render three empty items to enforce a height with CSS::
+
+ <ul>
+ {% for user in users %}
+ <li>{{ user.username }}</li>
+ {% endfor %}
+ {% for number in range(10 - users|count) %}
+ <li class="empty"><span>...</span></li>
+ {% endfor %}
+ </ul>
+
+.. function:: lipsum(n=5, html=True, min=20, max=100)
+
+ Generates some lorem ipsum for the template. By default, five paragraphs
+ of HTML are generated with each paragraph between 20 and 100 words.
+ If html is False, regular text is returned. This is useful to generate simple
+ contents for layout testing.
+
+.. function:: dict(\**items)
+
+ A convenient alternative to dict literals. ``{'foo': 'bar'}`` is the same
+ as ``dict(foo='bar')``.
+
+.. class:: cycler(\*items)
+
+ Cycle through values by yielding them one at a time, then restarting
+ once the end is reached.
+
+ Similar to ``loop.cycle``, but can be used outside loops or across
+ multiple loops. For example, render a list of folders and files in a
+ list, alternating giving them "odd" and "even" classes.
+
+ .. code-block:: html+jinja
+
+ {% set row_class = cycler("odd", "even") %}
+ <ul class="browser">
+ {% for folder in folders %}
+ <li class="folder {{ row_class.next() }}">{{ folder }}
+ {% endfor %}
+ {% for file in files %}
+ <li class="file {{ row_class.next() }}">{{ file }}
+ {% endfor %}
+ </ul>
+
+ :param items: Each positional argument will be yielded in the order
+ given for each cycle.
+
+ .. versionadded:: 2.1
+
+ .. method:: current
+ :property:
+
+ Return the current item. Equivalent to the item that will be
+ returned next time :meth:`next` is called.
+
+ .. method:: next()
+
+ Return the current item, then advance :attr:`current` to the
+ next item.
+
+ .. method:: reset()
+
+ Resets the current item to the first item.
+
+.. class:: joiner(sep=', ')
+
+ A tiny helper that can be used to "join" multiple sections. A joiner is
+ passed a string and will return that string every time it's called, except
+ the first time (in which case it returns an empty string). You can
+ use this to join things::
+
+ {% set pipe = joiner("|") %}
+ {% if categories %} {{ pipe() }}
+ Categories: {{ categories|join(", ") }}
+ {% endif %}
+ {% if author %} {{ pipe() }}
+ Author: {{ author() }}
+ {% endif %}
+ {% if can_edit %} {{ pipe() }}
+ <a href="?action=edit">Edit</a>
+ {% endif %}
+
+ .. versionadded:: 2.1
+
+.. class:: namespace(...)
+
+ Creates a new container that allows attribute assignment using the
+ ``{% set %}`` tag::
+
+ {% set ns = namespace() %}
+ {% set ns.foo = 'bar' %}
+
+ The main purpose of this is to allow carrying a value from within a loop
+ body to an outer scope. Initial values can be provided as a dict, as
+ keyword arguments, or both (same behavior as Python's `dict` constructor)::
+
+ {% set ns = namespace(found=false) %}
+ {% for item in items %}
+ {% if item.check_something() %}
+ {% set ns.found = true %}
+ {% endif %}
+ * {{ item.title }}
+ {% endfor %}
+ Found item having something: {{ ns.found }}
+
+ .. versionadded:: 2.10
+
+
+Extensions
+----------
+
+.. py:currentmodule:: jinja2
+
+The following sections cover the built-in Jinja extensions that may be
+enabled by an application. An application could also provide further
+extensions not covered by this documentation; in which case there should
+be a separate document explaining said :ref:`extensions
+<jinja-extensions>`.
+
+
+.. _i18n-in-templates:
+
+i18n
+~~~~
+
+If the :ref:`i18n-extension` is enabled, it's possible to mark text in
+the template as translatable. To mark a section as translatable, use a
+``trans`` block:
+
+.. code-block:: jinja
+
+ {% trans %}Hello, {{ user }}!{% endtrans %}
+
+Inside the block, no statements are allowed, only text and simple
+variable tags.
+
+Variable tags can only be a name, not attribute access, filters, or
+other expressions. To use an expression, bind it to a name in the
+``trans`` tag for use in the block.
+
+.. code-block:: jinja
+
+ {% trans user=user.username %}Hello, {{ user }}!{% endtrans %}
+
+To bind more than one expression, separate each with a comma (``,``).
+
+.. code-block:: jinja
+
+ {% trans book_title=book.title, author=author.name %}
+ This is {{ book_title }} by {{ author }}
+ {% endtrans %}
+
+To pluralize, specify both the singular and plural forms separated by
+the ``pluralize`` tag.
+
+.. code-block:: jinja
+
+ {% trans count=list|length %}
+ There is {{ count }} {{ name }} object.
+ {% pluralize %}
+ There are {{ count }} {{ name }} objects.
+ {% endtrans %}
+
+By default, the first variable in a block is used to determine whether
+to use singular or plural form. If that isn't correct, specify the
+variable used for pluralizing as a parameter to ``pluralize``.
+
+.. code-block:: jinja
+
+ {% trans ..., user_count=users|length %}...
+ {% pluralize user_count %}...{% endtrans %}
+
+When translating blocks of text, whitespace and linebreaks result in
+hard to read and error-prone translation strings. To avoid this, a trans
+block can be marked as trimmed, which will replace all linebreaks and
+the whitespace surrounding them with a single space and remove leading
+and trailing whitespace.
+
+.. code-block:: jinja
+
+ {% trans trimmed book_title=book.title %}
+ This is {{ book_title }}.
+ You should read it!
+ {% endtrans %}
+
+This results in ``This is %(book_title)s. You should read it!`` in the
+translation file.
+
+If trimming is enabled globally, the ``notrimmed`` modifier can be used
+to disable it for a block.
+
+.. versionadded:: 2.10
+ The ``trimmed`` and ``notrimmed`` modifiers have been added.
+
+If the translation depends on the context that the message appears in,
+the ``pgettext`` and ``npgettext`` functions take a ``context`` string
+as the first argument, which is used to select the appropriate
+translation. To specify a context with the ``{% trans %}`` tag, provide
+a string as the first token after ``trans``.
+
+.. code-block:: jinja
+
+ {% trans "fruit" %}apple{% endtrans %}
+ {% trans "fruit" trimmed count -%}
+ 1 apple
+ {%- pluralize -%}
+ {{ count }} apples
+ {%- endtrans %}
+
+.. versionadded:: 3.1
+ A context can be passed to the ``trans`` tag to use ``pgettext`` and
+ ``npgettext``.
+
+It's possible to translate strings in expressions with these functions:
+
+- ``_(message)``: Alias for ``gettext``.
+- ``gettext(message)``: Translate a message.
+- ``ngettext(singluar, plural, n)``: Translate a singular or plural
+ message based on a count variable.
+- ``pgettext(context, message)``: Like ``gettext()``, but picks the
+ translation based on the context string.
+- ``npgettext(context, singular, plural, n)``: Like ``npgettext()``,
+ but picks the translation based on the context string.
+
+You can print a translated string like this:
+
+.. code-block:: jinja
+
+ {{ _("Hello, World!") }}
+
+To use placeholders, use the ``format`` filter.
+
+.. code-block:: jinja
+
+ {{ _("Hello, %(user)s!")|format(user=user.username) }}
+
+Always use keyword arguments to ``format``, as other languages may not
+use the words in the same order.
+
+If :ref:`newstyle-gettext` calls are activated, using placeholders is
+easier. Formatting is part of the ``gettext`` call instead of using the
+``format`` filter.
+
+.. sourcecode:: jinja
+
+ {{ gettext('Hello World!') }}
+ {{ gettext('Hello %(name)s!', name='World') }}
+ {{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }}
+
+The ``ngettext`` function's format string automatically receives the
+count as a ``num`` parameter in addition to the given parameters.
+
+
+Expression Statement
+~~~~~~~~~~~~~~~~~~~~
+
+If the expression-statement extension is loaded, a tag called `do` is available
+that works exactly like the regular variable expression (``{{ ... }}``); except
+it doesn't print anything. This can be used to modify lists::
+
+ {% do navigation.append('a string') %}
+
+
+Loop Controls
+~~~~~~~~~~~~~
+
+If the application enables the :ref:`loopcontrols-extension`, it's possible to
+use `break` and `continue` in loops. When `break` is reached, the loop is
+terminated; if `continue` is reached, the processing is stopped and continues
+with the next iteration.
+
+Here's a loop that skips every second item::
+
+ {% for user in users %}
+ {%- if loop.index is even %}{% continue %}{% endif %}
+ ...
+ {% endfor %}
+
+Likewise, a loop that stops processing after the 10th iteration::
+
+ {% for user in users %}
+ {%- if loop.index >= 10 %}{% break %}{% endif %}
+ {%- endfor %}
+
+Note that ``loop.index`` starts with 1, and ``loop.index0`` starts with 0
+(See: :ref:`for-loop`).
+
+
+Debug Statement
+~~~~~~~~~~~~~~~
+
+If the :ref:`debug-extension` is enabled, a ``{% debug %}`` tag will be
+available to dump the current context as well as the available filters
+and tests. This is useful to see what's available to use in the template
+without setting up a debugger.
+
+.. code-block:: html+jinja
+
+ <pre>{% debug %}</pre>
+
+.. code-block:: text
+
+ {'context': {'cycler': <class 'jinja2.utils.Cycler'>,
+ ...,
+ 'namespace': <class 'jinja2.utils.Namespace'>},
+ 'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
+ ..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
+ 'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
+ ..., 'odd', 'sameas', 'sequence', 'string', 'undefined', 'upper']}
+
+
+With Statement
+~~~~~~~~~~~~~~
+
+.. versionadded:: 2.3
+
+The with statement makes it possible to create a new inner scope.
+Variables set within this scope are not visible outside of the scope.
+
+With in a nutshell::
+
+ {% with %}
+ {% set foo = 42 %}
+ {{ foo }} foo is 42 here
+ {% endwith %}
+ foo is not visible here any longer
+
+Because it is common to set variables at the beginning of the scope,
+you can do that within the `with` statement. The following two examples
+are equivalent::
+
+ {% with foo = 42 %}
+ {{ foo }}
+ {% endwith %}
+
+ {% with %}
+ {% set foo = 42 %}
+ {{ foo }}
+ {% endwith %}
+
+An important note on scoping here. In Jinja versions before 2.9 the
+behavior of referencing one variable to another had some unintended
+consequences. In particular one variable could refer to another defined
+in the same with block's opening statement. This caused issues with the
+cleaned up scoping behavior and has since been improved. In particular
+in newer Jinja versions the following code always refers to the variable
+`a` from outside the `with` block::
+
+ {% with a={}, b=a.attribute %}...{% endwith %}
+
+In earlier Jinja versions the `b` attribute would refer to the results of
+the first attribute. If you depend on this behavior you can rewrite it to
+use the ``set`` tag::
+
+ {% with a={} %}
+ {% set b = a.attribute %}
+ {% endwith %}
+
+.. admonition:: Extension
+
+ In older versions of Jinja (before 2.9) it was required to enable this
+ feature with an extension. It's now enabled by default.
+
+.. _autoescape-overrides:
+
+Autoescape Overrides
+--------------------
+
+.. versionadded:: 2.4
+
+If you want you can activate and deactivate the autoescaping from within
+the templates.
+
+Example::
+
+ {% autoescape true %}
+ Autoescaping is active within this block
+ {% endautoescape %}
+
+ {% autoescape false %}
+ Autoescaping is inactive within this block
+ {% endautoescape %}
+
+After an `endautoescape` the behavior is reverted to what it was before.
+
+.. admonition:: Extension
+
+ In older versions of Jinja (before 2.9) it was required to enable this
+ feature with an extension. It's now enabled by default.
diff --git a/docs/tricks.rst b/docs/tricks.rst
new file mode 100644
index 0000000..b58c5bb
--- /dev/null
+++ b/docs/tricks.rst
@@ -0,0 +1,100 @@
+Tips and Tricks
+===============
+
+.. highlight:: html+jinja
+
+This part of the documentation shows some tips and tricks for Jinja
+templates.
+
+
+.. _null-default-fallback:
+
+Null-Default Fallback
+---------------------
+
+Jinja supports dynamic inheritance and does not distinguish between parent
+and child template as long as no `extends` tag is visited. While this leads
+to the surprising behavior that everything before the first `extends` tag
+including whitespace is printed out instead of being ignored, it can be used
+for a neat trick.
+
+Usually child templates extend from one template that adds a basic HTML
+skeleton. However it's possible to put the `extends` tag into an `if` tag to
+only extend from the layout template if the `standalone` variable evaluates
+to false which it does per default if it's not defined. Additionally a very
+basic skeleton is added to the file so that if it's indeed rendered with
+`standalone` set to `True` a very basic HTML skeleton is added::
+
+ {% if not standalone %}{% extends 'default.html' %}{% endif -%}
+ <!DOCTYPE html>
+ <title>{% block title %}The Page Title{% endblock %}</title>
+ <link rel="stylesheet" href="style.css" type="text/css">
+ {% block body %}
+ <p>This is the page body.</p>
+ {% endblock %}
+
+
+Alternating Rows
+----------------
+
+If you want to have different styles for each row of a table or
+list you can use the `cycle` method on the `loop` object::
+
+ <ul>
+ {% for row in rows %}
+ <li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li>
+ {% endfor %}
+ </ul>
+
+`cycle` can take an unlimited number of strings. Each time this
+tag is encountered the next item from the list is rendered.
+
+
+Highlighting Active Menu Items
+------------------------------
+
+Often you want to have a navigation bar with an active navigation
+item. This is really simple to achieve. Because assignments outside
+of `block`\s in child templates are global and executed before the layout
+template is evaluated it's possible to define the active menu item in the
+child template::
+
+ {% extends "layout.html" %}
+ {% set active_page = "index" %}
+
+The layout template can then access `active_page`. Additionally it makes
+sense to define a default for that variable::
+
+ {% set navigation_bar = [
+ ('/', 'index', 'Index'),
+ ('/downloads/', 'downloads', 'Downloads'),
+ ('/about/', 'about', 'About')
+ ] -%}
+ {% set active_page = active_page|default('index') -%}
+ ...
+ <ul id="navigation">
+ {% for href, id, caption in navigation_bar %}
+ <li{% if id == active_page %} class="active"{% endif %}>
+ <a href="{{ href|e }}">{{ caption|e }}</a></li>
+ {% endfor %}
+ </ul>
+ ...
+
+.. _accessing-the-parent-loop:
+
+Accessing the parent Loop
+-------------------------
+
+The special `loop` variable always points to the innermost loop. If it's
+desired to have access to an outer loop it's possible to alias it::
+
+ <table>
+ {% for row in table %}
+ <tr>
+ {% set rowloop = loop %}
+ {% for cell in row %}
+ <td id="cell-{{ rowloop.index }}-{{ loop.index }}">{{ cell }}</td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </table>