diff --git a/src/jinja2/__init__.py b/__init__.py
similarity index 100%
rename from src/jinja2/__init__.py
rename to __init__.py
diff --git a/src/jinja2/_identifier.py b/_identifier.py
similarity index 100%
rename from src/jinja2/_identifier.py
rename to _identifier.py
diff --git a/artwork/jinjalogo.svg b/artwork/jinjalogo.svg
deleted file mode 100644
index 0bc9ea4..0000000
--- a/artwork/jinjalogo.svg
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
diff --git a/src/jinja2/async_utils.py b/async_utils.py
similarity index 100%
rename from src/jinja2/async_utils.py
rename to async_utils.py
diff --git a/src/jinja2/bccache.py b/bccache.py
similarity index 100%
rename from src/jinja2/bccache.py
rename to bccache.py
diff --git a/src/jinja2/compiler.py b/compiler.py
similarity index 100%
rename from src/jinja2/compiler.py
rename to compiler.py
diff --git a/src/jinja2/constants.py b/constants.py
similarity index 100%
rename from src/jinja2/constants.py
rename to constants.py
diff --git a/src/jinja2/debug.py b/debug.py
similarity index 100%
rename from src/jinja2/debug.py
rename to debug.py
diff --git a/src/jinja2/defaults.py b/defaults.py
similarity index 100%
rename from src/jinja2/defaults.py
rename to defaults.py
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index 5128596..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# 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
deleted file mode 100644
index 455b4c3..0000000
Binary files a/docs/_static/jinja-logo-sidebar.png and /dev/null differ
diff --git a/docs/_static/jinja-logo.png b/docs/_static/jinja-logo.png
deleted file mode 100644
index 7f8ca5b..0000000
Binary files a/docs/_static/jinja-logo.png and /dev/null differ
diff --git a/docs/api.rst b/docs/api.rst
deleted file mode 100644
index b2db537..0000000
--- a/docs/api.rst
+++ /dev/null
@@ -1,922 +0,0 @@
-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
-`.
-
-.. 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 `. 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 `` `` and ``
``
-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 = " \n"
-
- if eval_ctx.autoescape:
- value = escape(value)
- br = Markup(br)
-
- result = "\n\n".join(
- f"
{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 `. 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
-` 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
deleted file mode 100644
index 955deaf..0000000
--- a/docs/changes.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Changes
-=======
-
-.. include:: ../CHANGES.rst
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index f65d462..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,53 +0,0 @@
-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
deleted file mode 100644
index 46af67c..0000000
--- a/docs/examples/cache_extension.py
+++ /dev/null
@@ -1,54 +0,0 @@
-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
deleted file mode 100644
index bf8b9db..0000000
--- a/docs/examples/inline_gettext_extension.py
+++ /dev/null
@@ -1,72 +0,0 @@
-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::
-
-
_(Welcome)
-
_(This is a paragraph)
-
- 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
deleted file mode 100644
index 45ead3b..0000000
--- a/docs/extensions.rst
+++ /dev/null
@@ -1,423 +0,0 @@
-.. _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 `.
-
-.. _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 `.
-
-
-.. _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 %}
-
- ...
-
- {% 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
-
-
_(Welcome)
-
_(This is a paragraph)
-
-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
deleted file mode 100644
index 493dc38..0000000
--- a/docs/faq.rst
+++ /dev/null
@@ -1,75 +0,0 @@
-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
deleted file mode 100644
index 4ce2071..0000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-.. 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
deleted file mode 100644
index b945fb3..0000000
--- a/docs/integration.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-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
deleted file mode 100644
index fd6f84f..0000000
--- a/docs/intro.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-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
deleted file mode 100644
index a53a98c..0000000
--- a/docs/license.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-BSD-3-Clause License
-====================
-
-.. include:: ../LICENSE.rst
diff --git a/docs/make.bat b/docs/make.bat
deleted file mode 100644
index b162255..0000000
--- a/docs/make.bat
+++ /dev/null
@@ -1,35 +0,0 @@
-@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
deleted file mode 100644
index 1a08700..0000000
--- a/docs/nativetypes.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. 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
deleted file mode 100644
index fc9c31f..0000000
--- a/docs/sandbox.rst
+++ /dev/null
@@ -1,111 +0,0 @@
-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 ` 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
deleted file mode 100644
index caa35c3..0000000
--- a/docs/switching.rst
+++ /dev/null
@@ -1,181 +0,0 @@
-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 %}
-
{{ user }}
- {% endfor %}
-
-In Jinja, the ``loop`` context has a ``cycle`` method.
-
-.. code-block:: jinja
-
- {% for user in users %}
-
{{ user }}
- {% 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>
-
- % for item in list:
-
${item}
- % endfor
-
-
-Looks like this in Jinja with the above configuration:
-
-.. code-block:: jinja
-
- <% extends "layout.html" %>
- <% block title %>Page Title<% endblock %>
- <% block body %>
-
- % for item in list:
-
${item}
- % endfor
-
- <% endblock %>
diff --git a/docs/templates.rst b/docs/templates.rst
deleted file mode 100644
index 7a64750..0000000
--- a/docs/templates.rst
+++ /dev/null
@@ -1,1949 +0,0 @@
-.. 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::
-
-
-
-
- My Webpage
-
-
-
- {{ a_variable }}
-
- {# a comment #}
-
-
-
-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 `
-* ``{{ ... }}`` for :ref:`Expressions` to print to the template output
-* ``{# ... #}`` for :ref:`Comments` not included in the template output
-
-:ref:`Line Statements and Comments ` 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::
-
-
- {% if True %}
- yay
- {% endif %}
-
-
-gets rendered with blank lines inside the div::
-
-
-
- yay
-
-
-
-But with both `trim_blocks` and `lstrip_blocks` enabled, the template block
-lines are removed and other whitespace is preserved::
-
-
- yay
-
-
-You can manually disable the `lstrip_blocks` behavior by putting a
-plus sign (``+``) at the start of a block::
-
-
- {%+ if something %}yay{% endif %}
-
-
-Similarly, you can manually disable the ``trim_blocks`` behavior by
-putting a plus sign (``+``) at the end of a block::
-
-
- {% if something +%}
- yay
- {% endif %}
-
-
-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 %}
-
- {% for item in seq %}
-
{{ item }}
- {% endfor %}
-
- {% 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::
-
-
- # for item in seq
-
{{ item }}
- # endfor
-
-
-
- {% for item in seq %}
-
{{ item }}
- {% endfor %}
-
-
-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::
-
-
- # for href, caption in [('index.html', 'Index'),
- ('about.html', 'About')]:
-
-
-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:
-
{{ item }}
## 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::
-
-
-
-
- {% block head %}
-
- {% block title %}{% endblock %} - My Webpage
- {% endblock %}
-
-
-
{% block content %}{% endblock %}
-
-
-
-
-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() }}
-
- {% endblock %}
- {% block content %}
-
Index
-
- Welcome to my awesome homepage.
-
- {% 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::
-
- {% block title %}{% endblock %}
-
{{ self.title() }}
- {% 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 %}
-
Table Of Contents
- ...
- {{ 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 %}
-
{% block loop_item %}{{ item }}{% endblock %}
- {% endfor %}
-
-This example would output empty ``
`` 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 %}
-
- {% 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`::
-
-
Members
-
- {% for user in users %}
-
{{ user.username|e }}
- {% endfor %}
-
-
-As variables in templates retain their object properties, it is possible to
-iterate over containers like `dict`::
-
-
- {% for key, value in my_dict.items() %}
-
{{ key|e }}
-
{{ value|e }}
- {% endfor %}
-
-
-Python dicts may not be in the order you want to display them in. If
-order matters, use the ``|dictsort`` filter.
-
-.. code-block:: jinja
-
-
- {% for key, value in my_dict | dictsort %}
-
{{ key|e }}
-
{{ value|e }}
- {% endfor %}
-
-
-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 %}
-
{{ row }}
- {% 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 %}
-
{{ user.username|e }}
- {% 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`::
-
-
- {% for user in users %}
-
{{ user.username|e }}
- {% else %}
-
no users found
- {% endfor %}
-
-
-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::
-
-
-
-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) %}
-
{{ entry.category }}
- {% endif %}
-
{{ entry.message }}
- {% 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 %}
-
- {% for user in users %}
-
{{ user.username|e }}
- {% endfor %}
-
- {% 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 ` and for
-:ref:`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) -%}
-
- {%- endmacro %}
-
-The macro can then be called like a function in the namespace::
-
-
{{ input('username') }}
-
{{ input('password', type='password') }}
-
-If the macro was defined in a different template, you have to
-:ref:`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` 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` 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') -%}
-
-
{{ title }}
-
- {{ caller() }}
-
-
- {%- 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) -%}
-
- {% 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 %}
-
Downloads
- {% 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') -%}
-
- {%- endmacro %}
-
- {%- macro textarea(name, value='', rows=10, cols=40) -%}
-
- {%- 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 %}
-
-
Username
-
{{ forms.input('username') }}
-
Password
-
{{ forms.input('password', type='password') }}
-
-
{{ forms.textarea('comment') }}
-
-
-Alternatively, you can import specific names from a template into the current
-namespace::
-
- {% from 'forms.html' import input as input_field, textarea %}
-
-
Username
-
{{ input_field('username') }}
-
Password
-
{{ input_field('password', type='password') }}
-
-
{{ textarea('comment') }}
-
-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::
-
-
- {% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
- ('downloads.html', 'Downloads')] %}
-
-
-``('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 `.
-
-``|`` (pipe, vertical bar)
- Applies a :ref:`filter `.
-
-``~`` (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 `` if 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::
-
-
- {% for user in users %}
-
{{ user.username }}
- {% endfor %}
- {% for number in range(10 - users|count) %}
-
...
- {% endfor %}
-
-
-.. 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") %}
-
- {% for folder in folders %}
-
{{ folder }}
- {% endfor %}
- {% for file in files %}
-
{{ file }}
- {% endfor %}
-
-
- :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() }}
- Edit
- {% 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
-`.
-
-
-.. _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
-
-
{% debug %}
-
-.. code-block:: text
-
- {'context': {'cycler': ,
- ...,
- '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
deleted file mode 100644
index b58c5bb..0000000
--- a/docs/tricks.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-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 -%}
-
- {% block title %}The Page Title{% endblock %}
-
- {% block body %}
-
This is the page body.
- {% 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::
-
-
- {% for row in rows %}
-
{{ row }}
- {% endfor %}
-
-
-`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') -%}
- ...
-
- ...
-
-.. _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::
-
-
- {% for row in table %}
-
- {% set rowloop = loop %}
- {% for cell in row %}
-