From ee8d5b91e94f6920f846512c978b703f62545ca8 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Sat, 3 Jan 2015 23:05:34 +0100 Subject: [PATCH] Wrote main documentation for templates. --- docs/howto/custom-template-tags.txt | 2 + docs/intro/tutorial02.txt | 2 +- docs/ref/templates/api.txt | 263 ++--------- docs/ref/templates/language.txt | 8 +- docs/releases/1.2.txt | 11 +- docs/topics/http/shortcuts.txt | 4 +- docs/topics/templates.txt | 653 +++++++++++++++++++++++++++- 7 files changed, 695 insertions(+), 248 deletions(-) diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt index d69cedad35..b1b485489e 100644 --- a/docs/howto/custom-template-tags.txt +++ b/docs/howto/custom-template-tags.txt @@ -369,6 +369,8 @@ aware datetime, Django will convert it to the current time zone before passing it to your filter when appropriate, according to :ref:`rules for time zones conversions in templates `. +.. _howto-writing-custom-template-tags: + Writing custom template tags ---------------------------- diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index 8039994f40..a49d6b531c 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -578,7 +578,7 @@ more sensible to modify the *application's* templates, rather than those in the *project*. That way, you could include the polls application in any new project and be assured that it would find the custom templates it needed. -See the :ref:`template loader documentation ` for more +See the :ref:`template loading documentation ` for more information about how Django finds its templates. Customize the admin index page diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index dc2a7069ea..565ccc798e 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -2,56 +2,22 @@ The Django template language: For Python programmers ==================================================== -.. module:: django.template - :synopsis: Django's template system +.. currentmodule:: django.template This document explains the Django template system from a technical perspective -- how it works and how to extend it. If you're just looking for reference on the language syntax, see :doc:`/ref/templates/language`. +It assumes an understanding of templates, contexts, variables, tags, and +rendering. Start with the :ref:`introduction to the Django template language +` if you aren't familiar with these concepts. + If you're looking to use the Django template system as part of another application -- i.e., without the rest of the framework -- make sure to read the `configuration`_ section later in this document. .. _configuration: `configuring the template system in standalone mode`_ -Basics -====== - -A **template** is a text document, or a normal Python string, that is marked-up -using the Django template language. A template can contain **block tags** or -**variables**. - -A **block tag** is a symbol within a template that does something. - -This definition is deliberately vague. For example, a block tag can output -content, serve as a control structure (an "if" statement or "for" loop), grab -content from a database or enable access to other template tags. - -Block tags are surrounded by ``"{%"`` and ``"%}"``. - -Example template with block tags: - -.. code-block:: html+django - - {% if is_logged_in %}Thanks for logging in!{% else %}Please log in.{% endif %} - -A **variable** is a symbol within a template that outputs a value. - -Variable tags are surrounded by ``"{{"`` and ``"}}"``. - -Example template with variables: - -.. code-block:: html+django - - My first name is {{ first_name }}. My last name is {{ last_name }}. - -A **context** is a "variable name" -> "variable value" mapping that is passed -to a template. - -A template **renders** a context by replacing the variable "holes" with values -from the context and executing all block tags. - Using the template system ========================= @@ -87,7 +53,7 @@ takes one argument -- the raw template code:: Rendering a context ------------------- -.. method:: render(context) +.. method:: Template.render(context) Once you have a compiled ``Template`` object, you can render a context -- or multiple contexts -- with it. The ``Context`` class lives at @@ -518,6 +484,11 @@ optional, third positional argument, ``processors``. In this example, the the same as a call to :func:`~django.shortcuts.render_to_response()` with a ``context_instance`` argument that forces the use of a ``RequestContext``. +.. _context-processors: + +Context processors +------------------ + Here's what each of the default processors does: django.contrib.auth.context_processors.auth @@ -658,88 +629,6 @@ such as ``.html`` or ``.txt``, or they can have no extension at all. Note that these paths should use Unix-style forward slashes, even on Windows. -.. _ref-templates-api-the-python-api: - -The Python API -~~~~~~~~~~~~~~ - -.. module:: django.template.loader - -``django.template.loader`` has two functions to load templates from files: - -.. function:: get_template(template_name[, dirs]) - - ``get_template`` returns the compiled template (a ``Template`` object) for - the template with the given name. If the template doesn't exist, it raises - ``django.template.TemplateDoesNotExist``. - - .. versionchanged:: 1.7 - - The ``dirs`` parameter was added. - - .. versionchanged:: 1.8 - - The ``dirs`` parameter was deprecated. - -.. function:: select_template(template_name_list[, dirs]) - - ``select_template`` is just like ``get_template``, except it takes a list - of template names. Of the list, it returns the first template that exists. - - .. versionchanged:: 1.7 - - The ``dirs`` parameter was added. - - .. versionchanged:: 1.8 - - The ``dirs`` parameter was deprecated. - -For example, if you call ``get_template('story_detail.html')`` and have the -above :setting:`DIRS ` option, here are the files Django will -look for, in order: - -* ``/home/html/templates/lawrence.com/story_detail.html`` -* ``/home/html/templates/default/story_detail.html`` - -If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``, -here's what Django will look for: - -* ``/home/html/templates/lawrence.com/story_253_detail.html`` -* ``/home/html/templates/default/story_253_detail.html`` -* ``/home/html/templates/lawrence.com/story_detail.html`` -* ``/home/html/templates/default/story_detail.html`` - -When Django finds a template that exists, it stops looking. - -.. admonition:: Tip - - You can use ``select_template()`` for super-flexible "templatability." For - example, if you've written a news story and want some stories to have - custom templates, use something like - ``select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])``. - That'll allow you to use a custom template for an individual story, with a - fallback template for stories that don't have custom templates. - -Using subdirectories -~~~~~~~~~~~~~~~~~~~~ - -It's possible -- and preferable -- to organize templates in subdirectories of -the template directory. The convention is to make a subdirectory for each -Django app, with subdirectories within those subdirectories as needed. - -Do this for your own sanity. Storing all templates in the root level of a -single directory gets messy. - -To load a template that's within a subdirectory, just use a slash, like so:: - - get_template('news/story_detail.html') - -Using the same :setting:`DIRS ` option from above, this -example ``get_template()`` call will attempt to load the following templates: - -* ``/home/html/templates/lawrence.com/news/story_detail.html`` -* ``/home/html/templates/default/news/story_detail.html`` - .. _template-loaders: Loader types @@ -892,6 +781,26 @@ loaders that come with Django: Django uses the template loaders in order according to the ``'loaders'`` option. It uses each loader until a loader finds a match. +.. _custom-template-loaders: + +Custom loaders +~~~~~~~~~~~~~~ + +Custom ``Loader`` classes should inherit from +``django.template.loaders.base.Loader`` and override the +``load_template_source()`` method, which takes a ``template_name`` argument, +loads the template from disk (or elsewhere), and returns a tuple: +``(template_string, template_origin)``. + +.. versionchanged:: 1.8 + + ``django.template.loaders.base.Loader`` used to be defined at + ``django.template.loader.BaseLoader``. + +The ``load_template()`` method of the ``Loader`` class retrieves the template +string by calling ``load_template_source()``, instantiates a ``Template`` from +the template source, and returns a tuple: ``(template, template_origin)``. + .. currentmodule:: django.template Template origin @@ -927,48 +836,6 @@ When :setting:`TEMPLATE_DEBUG` is ``True`` template objects will have an The string used to create the template. -The ``render_to_string`` shortcut -=================================== - -.. function:: loader.render_to_string(template_name, context=None, context_instance=None) - -To cut down on the repetitive nature of loading and rendering -templates, Django provides a shortcut function which largely -automates the process: ``render_to_string()`` in -:mod:`django.template.loader`, which loads a template, renders it and -returns the resulting string:: - - from django.template.loader import render_to_string - rendered = render_to_string('my_template.html', {'foo': 'bar'}) - -The ``render_to_string`` shortcut takes one required argument -- -``template_name``, which should be the name of the template to load -and render (or a list of template names, in which case Django will use -the first template in the list that exists) -- and two optional arguments: - -``context`` - A dictionary to be used as variables and values for the - template's context. This should be passed as the second - positional argument. - - .. versionchanged:: 1.8 - - The ``context`` argument used to be called ``dictionary``. That name - is deprecated in Django 1.8 and will be removed in Django 2.0. - -``context_instance`` - An instance of :class:`~django.template.Context` or a subclass (e.g., an - instance of :class:`~django.template.RequestContext`) to use as the - template's context. This can also be passed as the third positional argument. - - .. deprecated:: 1.8 - - The ``context_instance`` argument is deprecated. Simply use ``context``. - -See also the :func:`~django.shortcuts.render_to_response()` shortcut, which -calls ``render_to_string`` and feeds the result into an :class:`~django.http.HttpResponse` -suitable for returning directly from a view. - Configuring the template system in standalone mode ================================================== @@ -998,71 +865,3 @@ and :setting:`TEMPLATE_DEBUG`. If you plan to use the :ttag:`url` template tag, you will also need to set the :setting:`ROOT_URLCONF` setting. All available settings are described in the :doc:`settings documentation `, and any setting starting with ``TEMPLATE_`` is of obvious interest. - -.. _topic-template-alternate-language: - -Using an alternative template language -====================================== - -The Django ``Template`` and ``Loader`` classes implement a simple API for -loading and rendering templates. By providing some simple wrapper classes that -implement this API we can use third party template systems like `Jinja2 -`_. This -allows us to use third-party template libraries without giving up useful Django -features like the Django ``Context`` object and handy shortcuts like -:func:`~django.shortcuts.render_to_response()`. - -The core component of the Django templating system is the ``Template`` class. -This class has a very simple interface: it has a constructor that takes a single -positional argument specifying the template string, and a ``render()`` method -that takes a :class:`~django.template.Context` object and returns a string -containing the rendered response. - -Suppose we're using a template language that defines a ``Template`` object with -a ``render()`` method that takes a dictionary rather than a ``Context`` object. -We can write a simple wrapper that implements the Django ``Template`` interface:: - - import some_template_language - class Template(some_template_language.Template): - def render(self, context): - # flatten the Django Context into a single dictionary. - context_dict = {} - for d in context.dicts: - context_dict.update(d) - return super(Template, self).render(context_dict) - -That's all that's required to make our fictional ``Template`` class compatible -with the Django loading and rendering system! - -The next step is to write a ``Loader`` class that returns instances of our custom -template class instead of the default :class:`~django.template.Template`. Custom ``Loader`` -classes should inherit from ``django.template.loaders.base.Loader`` and override -the ``load_template_source()`` method, which takes a ``template_name`` argument, -loads the template from disk (or elsewhere), and returns a tuple: -``(template_string, template_origin)``. - -.. versionchanged:: 1.8 - - ``django.template.loaders.base.Loader`` used to be defined at - ``django.template.loader.BaseLoader``. - -The ``load_template()`` method of the ``Loader`` class retrieves the template -string by calling ``load_template_source()``, instantiates a ``Template`` from -the template source, and returns a tuple: ``(template, template_origin)``. Since -this is the method that actually instantiates the ``Template``, we'll need to -override it to use our custom template class instead. We can inherit from the -builtin :class:`django.template.loaders.app_directories.Loader` to take advantage -of the ``load_template_source()`` method implemented there:: - - from django.template.loaders import app_directories - class Loader(app_directories.Loader): - is_usable = True - - def load_template(self, template_name, template_dirs=None): - source, origin = self.load_template_source(template_name, template_dirs) - template = Template(source) - return template, origin - -Finally, we need to modify our project settings, telling Django to use our custom -loader. Now we can write all of our templates in our alternative template -language while continuing to use the rest of the Django templating system. diff --git a/docs/ref/templates/language.txt b/docs/ref/templates/language.txt index dc145924c9..c7dcbe1240 100644 --- a/docs/ref/templates/language.txt +++ b/docs/ref/templates/language.txt @@ -2,11 +2,9 @@ The Django template language ============================ -.. admonition:: About this document - - This document explains the language syntax of the Django template system. If - you're looking for a more technical perspective on how it works and how to - extend it, see :doc:`/ref/templates/api`. +This document explains the language syntax of the Django template system. If +you're looking for a more technical perspective on how it works and how to +extend it, see :doc:`/ref/templates/api`. Django's template language is designed to strike a balance between power and ease. It's designed to feel comfortable to those used to working with HTML. If diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt index 6d06fa49b2..218ca4d7e9 100644 --- a/docs/releases/1.2.txt +++ b/docs/releases/1.2.txt @@ -253,8 +253,7 @@ lots of smaller subtemplates (using the ``{% extends %}`` or ``{% include %}`` tags). As a side effect, it is now much easier to support non-Django template -languages. For more details, see the :ref:`notes on supporting -non-Django template languages`. +languages. Class-based template loaders ---------------------------- @@ -275,9 +274,8 @@ If you have developed your own custom template loaders we suggest to consider porting them to a class-based implementation because the code for backwards compatibility with function-based loaders starts its deprecation process in Django 1.2 and will be removed in Django 1.4. There is a description of the -API these loader classes must implement :ref:`here -` and you can also examine the source code -of the loaders shipped with Django. +API these loader classes must implement in the template API reference and you +can also examine the source code of the loaders shipped with Django. Natural keys in fixtures ------------------------ @@ -1172,5 +1170,4 @@ Function-based template loaders Django 1.2 changes the template loading mechanism to use a class-based approach. Old style function-based template loaders will still work, but should -be updated to use the new :ref:`class-based template loaders -`. +be updated to use the new class-based template loaders. diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt index d3971fb711..d31572dd4d 100644 --- a/docs/topics/http/shortcuts.txt +++ b/docs/topics/http/shortcuts.txt @@ -124,8 +124,8 @@ Required arguments ``template_name`` The full name of a template to use or sequence of template names. If a sequence is given, the first template that exists will be used. See the - :ref:`template loader documentation ` - for more information on how templates are found. + :ref:`template loading documentation ` for more + information on how templates are found. Optional arguments ------------------ diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index 1b53a9d4f5..30e1b9b011 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -1 +1,652 @@ -TODO - explain multiple template engines and the django template language +========= +Templates +========= + +.. module:: django.template + :synopsis: Django's template system + +Being a web framework, Django needs a convenient way to generate HTML +dynamically. The most common approach relies on templates. A template contains +the static parts of the desired HTML output as well as some special syntax +describing how dynamic content will be inserted. For a hands-on example of +creating HTML pages with templates, see :doc:`Tutorial 3 `. + +A Django project can be configured with one or several template engines (or +even zero if you don't use templates). Django ships built-in backends for its +own template system, creatively called the Django template language (DTL), and +for the popular alternative Jinja2_. Backends for other template languages may +be available from third-parties. + +Django defines a standard API for loading and rendering templates regardless +of the backend. Loading consists of finding the template for a given identifier +and preprocessing it, usually compiling it to an in-memory representation. +Rendering means interpolating the template with context data and returning the +resulting string. + +The :doc:`Django template language ` is Django's own +template system. Until Django 1.8 it was the only built-in option available. +It's a good template library even though it's fairly opinionated and sports a +few idiosyncrasies. If you don't have a pressing reason to choose another +backend, you should use the DTL, especially if you're writing a pluggable +application and you intend to distribute templates. Django's contrib apps that +include templates, like :doc:`django.contrib.admin `, +use the DTL. + +For historical reasons, both the generic support for template engines and the +implementation of the Django template language live in the ``django.template`` +namespace. + +.. _template-engines: + +Support for template engines +============================ + +.. versionadded:: 1.8 + + Support for multiple template engines and the :setting:`TEMPLATES` setting + were added in Django 1.8. + +Configuration +------------- + +Templates engines are configured with the :setting:`TEMPLATES` setting. It's a +list of configurations, one for each engine. The default value is empty. The +``settings.py`` generated by the :djadmin:`startproject` command defines a +more useful value:: + + TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + # ... some options here ... + }, + }, + ] + +:setting:`BACKEND ` is a dotted Python path to a template +engine class implementing Django's template backend API. The built-in backends +are :class:`django.template.backends.django.DjangoTemplates` and +:class:`django.template.backends.jinja2.Jinja2`. + +Since most engines load templates from files, the top-level configuration for +each engine contains two common settings: + +* :setting:`DIRS ` defines a list of directories where the + engine should look for template source files, in search order. +* :setting:`APP_DIRS ` tells whether the engine should + look for templates inside installed applications. Each backend defines a + conventional name for the subdirectory inside applications where its + templates should be stored. + +While uncommon, it's possible to configure several instances of the same +backend with different options. In that case you should define a unique +:setting:`NAME ` for each engine. + +:setting:`OPTIONS ` contains backend-specific settings. + +Usage +----- + +.. _template-loading: + +.. module:: django.template.loader + +The ``django.template.loader`` module defines two functions to load templates. + +.. function:: get_template(template_name[, dirs][, using]) + + This function loads the template with the given name and returns a + ``Template`` object. + + The exact type of the return value depends on the backend that loaded the + template. Each backend has its own ``Template`` class. + + ``get_template()`` tries each template engine in order until one succeeds. + If the template cannot be found, it raises + :exc:`~django.template.TemplateDoesNotExist`. If the template is found but + contains invalid syntax, it raises + :exc:`~django.template.TemplateSyntaxError`. + + How templates are searched and loaded depends on each engine's backend and + configuration. + + If you want to restrict the search to a particular template engine, pass + the engine's :setting:`NAME ` in the ``using`` argument. + + .. versionchanged:: 1.7 + + The ``dirs`` parameter was added. + + .. deprecated:: 1.8 + + The ``dirs`` parameter was deprecated. + + .. versionchanged:: 1.8 + + The ``using`` parameter was added. + + .. versionchanged:: 1.8 + + ``get_template()`` returns a backend-dependent ``Template`` instead + of a :class:`django.template.Template`. + +.. function:: select_template(template_name_list[, dirs][, using]) + + ``select_template()`` is just like ``get_template()``, except it takes a + list of template names. It tries each name in order and returns the first + template that exists. + + .. versionchanged:: 1.7 + + The ``dirs`` parameter was added. + + .. deprecated:: 1.8 + + The ``dirs`` parameter was deprecated. + + .. versionchanged:: 1.8 + + The ``using`` parameter was added. + + .. versionchanged:: 1.8 + + ``select_template()`` returns a backend-dependent ``Template`` instead + of a :class:`django.template.Template`. + +.. currentmodule:: django.template + +If loading a template fails, the following two exceptions, defined in +``django.template``, may be raised: + +.. exception:: TemplateDoesNotExist + + This exception is raised when a template cannot be found. + +.. exception:: TemplateSyntaxError + + This exception is raised when a template was found but contains errors. + +``Template`` objects returned by ``get_template()`` and ``select_template()`` +must provide a ``render()`` method with the following signature: + +.. currentmodule:: django.template.backends.base + +.. method:: Template.render(context=None, request=None) + + Renders this template with a given context. + + If ``context`` is provided, it must be a :class:`dict`. If it isn't + provided, the engine will render the template with an empty context. + + If ``request`` is provided, it must be an :class:`~django.http.HttpRequest`. + Then the engine must make it, as well as the CSRF token, available in the + template. How this is achieved is up to each backend. + +Here's an example of the search algorithm. For this example the +:setting:`TEMPLATES` setting is:: + + TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + '/home/html/example.com', + '/home/html/default', + ], + }, + { + 'BACKEND': 'django.template.backends.jinja2.Jinja2', + 'DIRS': [ + '/home/html/jinja2', + ], + }, + ] + +If you call ``get_template('story_detail.html')``, here are the files Django +will look for, in order: + +* ``/home/html/example.com/story_detail.html`` (``'django'`` engine) +* ``/home/html/default/story_detail.html`` (``'django'`` engine) +* ``/home/html/jinja2/story_detail.html`` (``'jinja2'`` engine) + +If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``, +here's what Django will look for: + +* ``/home/html/example.com/story_253_detail.html`` (``'django'`` engine) +* ``/home/html/default/story_253_detail.html`` (``'django'`` engine) +* ``/home/html/jinja2/story_253_detail.html`` (``'jinja2'`` engine) +* ``/home/html/example.com/story_detail.html`` (``'django'`` engine) +* ``/home/html/default/story_detail.html`` (``'django'`` engine) +* ``/home/html/jinja2/story_detail.html`` (``'jinja2'`` engine) + +When Django finds a template that exists, it stops looking. + +.. admonition:: Tip + + You can use :func:`~django.template.loader.select_template()` for flexible + template loading. For example, if you've written a news story and want + some stories to have custom templates, use something like + ``select_template(['story_%s_detail.html' % story.id, + 'story_detail.html'])``. That'll allow you to use a custom template for an + individual story, with a fallback template for stories that don't have + custom templates. + +It's possible -- and preferable -- to organize templates in subdirectories +inside each directory containing templates. The convention is to make a +subdirectory for each Django app, with subdirectories within those +subdirectories as needed. + +Do this for your own sanity. Storing all templates in the root level of a +single directory gets messy. + +To load a template that's within a subdirectory, just use a slash, like so:: + + get_template('news/story_detail.html') + +Using the same :setting:`TEMPLATES` option as above, this will attempt to load +the following templates: + +* ``/home/html/example.com/news/story_detail.html`` (``'django'`` engine) +* ``/home/html/default/news/story_detail.html`` (``'django'`` engine) +* ``/home/html/jinja2/news/story_detail.html`` (``'jinja2'`` engine) + +.. currentmodule:: django.template.loader + +In addition, to cut down on the repetitive nature of loading and rendering +templates, Django provides a shortcut function which automates the process. + +.. function:: render_to_string(template_name[, context][, context_instance][, request][, using]) + + ``render_to_string()`` loads a template like :func:`get_template` and + calls its ``render()`` method immediately. It takes the following + arguments. + + ``template_name`` + The name of the template to load and render. If it's a list of template + names, Django uses :func:`select_template` instead of + :func:`get_template` to find the template. + + ``context`` + A :class:`dict` to be used as the template's context for rendering. + + .. versionchanged:: 1.8 + + The ``context`` argument used to be called ``dictionary``. That name + is deprecated in Django 1.8 and will be removed in Django 2.0. + + ``context`` is now optional. An empty context will be used if it + isn't provided. + + ``context_instance`` + An instance of :class:`~django.template.Context` or a subclass (e.g., an + instance of :class:`~django.template.RequestContext`) to use as the + template's context. + + .. deprecated:: 1.8 + + The ``context_instance`` argument is deprecated. Use ``context`` and + if needed ``request``. + + ``request`` + An optional :class:`~django.http.HttpRequest` that will be available + during the template's rendering process. + + .. versionadded:: 1.8 + + The ``request`` argument was added. + +See also the :func:`~django.shortcuts.render()` and +:func:`~django.shortcuts.render_to_response()` shortcuts, which call +:func:`render_to_string()` and feed the result into an +:class:`~django.http.HttpResponse` suitable for returning from a view. + +Finally, you can use configured engines directly: + +.. data:: engines + + Template engines are available in ``django.template.engines``:: + + from django.template import engines + + django_engine = engines['django'] + template = django_engine.from_string("Hello {{ name }}!") + + The lookup key — ``'django'`` in this example — is the engine's + :setting:`NAME `. + +.. module:: django.template.backends + +Built-in backends +----------------- + +.. module:: django.template.backends.django + +.. class:: DjangoTemplates + +Set :setting:`BACKEND ` to +``'django.template.backends.django.DjangoTemplates'`` to configure a Django +template engine. + +When :setting:`APP_DIRS ` is ``True``, ``DjangoTemplates`` +engines look for templates in the ``templates`` subdirectory of installed +applications. This generic name was kept for backwards-compatibility. + +``DjangoTemplates`` engines accept the following :setting:`OPTIONS +`: + +* ``'allowed_include_roots'``: a list of strings representing allowed prefixes + for the ``{% ssi %}`` template tag. This is a security measure, so that + template authors can't access files that they shouldn't be accessing. + + For example, if ``'allowed_include_roots'`` is ``['/home/html', + '/var/www']``, then ``{% ssi /home/html/foo.txt %}`` would work, but ``{% + ssi /etc/passwd %}`` wouldn't. + + It defaults to an empty list. + + .. deprecated:: 1.8 + + ``allowed_include_roots`` is deprecated because the {% ssi %} tag is + deprecated. + +* ``'context_processors'``: a list of dotted Python paths to callables that + are used to populate the context when a template is rendered with a request. + These callables take a request object as their argument and return a + :class:`dict` of items to be merged into the context. + + It defaults to an empty list. + + See :class:`~django.template.RequestContext` for more information. + +* ``'debug'``: a boolean that turns on/off template debug mode. If it is + ``True``, the fancy error page will display a detailed report for any + exception raised during template rendering. This report contains the + relevant snippet of the template with the appropriate line highlighted. + + It defaults to the value of the :setting:`TEMPLATE_DEBUG` setting. The + setting is convenient for toggling template debug mode globally rather than + on a per-engine basis. + +* ``'loaders'``: a list of dotted Python paths to template loader classes. + Each ``Loader`` class knows how to import templates from a particular + source. Optionally, a tuple can be used instead of a string. The first item + in the tuple should be the ``Loader`` class name, and subsequent items are + passed to the ``Loader`` during initialization. + + The default depends on the values of :setting:`DIRS ` and + :setting:`APP_DIRS `. + + See :ref:`template-loaders` for details. + +* ``'string_if_invalid'``: the output, as a string, that the template system + should use for invalid (e.g. misspelled) variables. + + It defaults to an empty string. + + See :ref:`invalid-template-variables` for details. + +* ``'file_charset'``: the charset used to read template files on disk. + + It defaults to the value of :setting:`FILE_CHARSET`. + +.. module:: django.template.backends.jinja2 + +.. class:: Jinja2 + +Set :setting:`BACKEND ` to +``'django.template.backends.jinja2.Jinja2'`` to configure a Jinja2_ engine. + +When :setting:`APP_DIRS ` is ``True``, ``Jinja2`` engines +look for templates in the ``jinja2`` subdirectory of installed applications. + +The most important entry in :setting:`OPTIONS ` is +``'environment'``. It's a dotted Python path to a callable returning a Jinja2 +environment. It defaults to ``'jinja2.Environment'``. Django invokes that +callable and passes other options as keyword arguments. Furthermore, Django +adds defaults that differ from Jinja2's for a few options: + +* ``'autoescape'``: ``True`` +* ``'loader'``: a loader configured for :setting:`DIRS ` and + :setting:`APP_DIRS ` +* ``'auto_reload'``: ``settings.DEBUG`` +* ``'undefined'``: ``DebugUndefined if settings.DEBUG else Undefined`` + +Custom backends +--------------- + +Here's how to implement a custom template backend in order to use another +template system. A template backend is a class that inherits +``django.template.backends.base.BaseEngine``. It must implement +``get_template()`` and optionally ``from_string()``. Here's an example for a +fictional ``foobar`` template library:: + + from django.template import TemplateDoesNotExist, TemplateSyntaxError + from django.template.backends.base import BaseEngine + from django.template.backends.utils import csrf_input_lazy, csrf_token_lazy + + import foobar + + + class FooBar(BaseEngine): + + # Name of the subdirectory containing the templates for this engine + # inside an installed application. + app_dirname = 'foobar' + + def __init__(self, params): + params = params.copy() + options = params.pop('OPTIONS').copy() + super(FooBar, self).__init__(params) + + self.engine = foobar.Engine(**options) + + + def from_string(self, template_code): + try: + return Template(self.engine.from_string(template_code)) + except foobar.TemplateCompilationFailed as exc: + raise TemplateSyntaxError(exc.args) + + def get_template(self, template_name): + try: + return Template(self.engine.get_template(template_name)) + except foobar.TemplateNotFound as exc: + raise TemplateDoesNotExist(exc.args) + except foobar.TemplateCompilationFailed as exc: + raise TemplateSyntaxError(exc.args) + + + class Template(object): + + def __init__(self, template): + self.template = template + + def render(self, context=None, request=None): + if context is None: + context = {} + if request is not None: + context['request'] = request + context['csrf_input'] = csrf_input_lazy(request) + context['csrf_token'] = csrf_token_lazy(request) + return self.template.render(context) + +See `DEP 182`_ for more information. + +.. currentmodule:: django.template + +.. _template-language-intro: + +The Django template language +============================ + +.. highlightlang:: html+django + +Syntax +------ + +.. admonition:: About this section + + This is an overview of the Django template language's syntax. For details + see the :doc:`language syntax reference `. + +A Django template is simply a text document or a Python string marked-up using +the Django template language. Some constructs are recognized and interpreted +by the template engine. The main ones are variables and tags. + +A template is rendered with a context. Rendering replaces variables with their +values, which are looked up in the context, and executes tags. Everything else +is output as is. + +The syntax of the Django template language involves four constructs. + +Variables +~~~~~~~~~ + +A variable outputs a value from the context, which is a dict-like object +mapping keys to values. + +Variables are surrounded by ``{{`` and ``}}`` like this:: + + My first name is {{ first_name }}. My last name is {{ last_name }}. + +With a context of ``{'first_name': 'John', 'last_name': 'Doe'}``, this +template renders to:: + + My first name is John. My last name is Doe. + +Dictionary lookup, attribute lookup and list-index lookups are implemented +with a dot notation:: + + {{ my_dict.key }} + {{ my_object.attribute }} + {{ my_list.0 }} + +If a variable resolves to a callable, the template system will call it with no +arguments and use its result instead of the callable. + +Tags +~~~~ + +Tags provide arbitrary logic in the rendering process. + +This definition is deliberately vague. For example, a tag can output content, +serve as a control structure e.g. an "if" statement or a "for" loop, grab +content from a database, or even enable access to other template tags. + +Tags are surrounded by ``{%`` and ``%}`` like this:: + + {% csrf_token %} + +Most tags accept arguments:: + + {% cycle 'odd' 'even' %} + +Some tags require beginning and ending tags:: + + {% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %} + +A :ref:`reference of built-in tags ` is +available as well as :ref:`instructions for writing custom tags +`. + +Filters +~~~~~~~ + +Filters transform the values of variables and tag arguments. + +They look like this:: + + {{ django|title }} + +With a context of ``{'django': 'the web framework for perfectionists with +deadlines'}``, this template renders to:: + + The Web Framework For Perfectionists With Deadlines + +Some filters take an argument:: + + {{ my_date|date:"Y-m-d" }} + +A :ref:`reference of built-in filters ` is +available as well as :ref:`instructions for writing custom filters +`. + +Comments +~~~~~~~~ + +Comments look like this:: + + {# this won't be rendered #} + +A :ttag:`{% comment %} ` tag provides multi-line comments. + +Components +---------- + +.. admonition:: About this section + + This is an overview of the Django template language's APIs. For details + see the :doc:`API reference `. + +Engine +~~~~~~ + +:class:`django.template.Engine` encapsulates an instance of the Django +template system. The main reason for instantiating an +:class:`~django.template.Engine` directly is to use the Django template +language outside of a Django project. + +:class:`django.template.backends.django.DjangoTemplates` is a thin wrapper +adapting :class:`django.template.Engine` to Django's template backend API. + +Template +~~~~~~~~ + +:class:`django.template.Template` represents a compiled template. +Templates are obtained with :meth:`Engine.get_template() +` or :meth:`Engine.from_string() +` + +Likewise ``django.template.backends.django.Template`` is a thin wrapper +adapting :class:`django.template.Template` to the common template API. + +Context +~~~~~~~ + +:class:`django.template.Context` holds some metadata in addition to the +context data. It is passed to :meth:`Template.render() +` for rendering a template. + +:class:`django.template.RequestContext` is a subclass of +:class:`~django.template.Context` that stores the current +:class:`~django.http.HttpRequest` and runs template context processors. + +The common API doesn't have an equivalent concept. Context data is passed in a +plain :class:`dict` and the current :class:`~django.http.HttpRequest` is passed +separately if needed. + +Loaders +~~~~~~~ + +Template loaders are responsible for locating templates, loading them, and +returning :class:`~django.template.Template` objects. + +Django provides several :ref:`built-in template loaders ` +and supports :ref:`custom template loaders `. + +Context processors +~~~~~~~~~~~~~~~~~~ + +Context processors are functions that receive the current +:class:`~django.http.HttpRequest` as an argument and return a :class:`dict` of +data to be added to the rendering context. + +Their main use is to add common data shared by all templates to the context +without repeating code in every view. + +Django provides many :ref:`built-in context processors `. +Implementing a custom context processor is as simple as defining a function. + +.. _Jinja2: http://jinja.pocoo.org/ +.. _DEP 182: https://github.com/django/deps/blob/master/accepted/0182-multiple-template-engines.rst