mirror of
				https://github.com/django/django.git
				synced 2025-10-25 14:46:09 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			804 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			804 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =========
 | |
| 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 </intro/tutorial03>`.
 | |
| 
 | |
| 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 </ref/templates/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 </ref/contrib/admin/index>`,
 | |
| 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
 | |
| ============================
 | |
| 
 | |
| 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 <TEMPLATES-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 <TEMPLATES-DIRS>` defines a list of directories where the
 | |
|   engine should look for template source files, in search order.
 | |
| * :setting:`APP_DIRS <TEMPLATES-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 <TEMPLATES-NAME>` for each engine.
 | |
| 
 | |
| :setting:`OPTIONS <TEMPLATES-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, using=None)
 | |
| 
 | |
|     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 <TEMPLATES-NAME>` in the ``using`` argument.
 | |
| 
 | |
| .. function:: select_template(template_name_list, using=None)
 | |
| 
 | |
|     ``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.
 | |
| 
 | |
| .. currentmodule:: django.template
 | |
| 
 | |
| If loading a template fails, the following two exceptions, defined in
 | |
| ``django.template``, may be raised:
 | |
| 
 | |
| .. exception:: TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)
 | |
| 
 | |
|     This exception is raised when a template cannot be found. It accepts the
 | |
|     following optional arguments for populating the :ref:`template postmortem
 | |
|     <template-postmortem>` on the debug page:
 | |
| 
 | |
|     ``backend``
 | |
|         The template backend instance from which the exception originated.
 | |
| 
 | |
|     ``tried``
 | |
|         A list of sources that were tried when finding the template. This is
 | |
|         formatted as a list of tuples containing ``(origin, status)``, where
 | |
|         ``origin`` is an :ref:`origin-like <template-origin-api>` object and
 | |
|         ``status`` is a string with the reason the template wasn't found.
 | |
| 
 | |
|     ``chain``
 | |
|         A list of intermediate :exc:`~django.template.TemplateDoesNotExist`
 | |
|         exceptions raised when trying to load a template. This is used by
 | |
|         functions, such as :func:`~django.template.loader.get_template`, that
 | |
|         try to load a given template from multiple engines.
 | |
| 
 | |
| .. exception:: TemplateSyntaxError(msg)
 | |
| 
 | |
|     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=None, request=None, using=None)
 | |
| 
 | |
|     ``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.
 | |
| 
 | |
|     ``request``
 | |
|         An optional :class:`~django.http.HttpRequest` that will be available
 | |
|         during the template's rendering process.
 | |
| 
 | |
|     Usage example::
 | |
| 
 | |
|         from django.template.loader import render_to_string
 | |
|         rendered = render_to_string('my_template.html', {'foo': 'bar'})
 | |
| 
 | |
| See also the :func:`~django.shortcuts.render()` shortcut which calls
 | |
| :func:`render_to_string()` and feeds 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 <TEMPLATES-NAME>`.
 | |
| 
 | |
| .. module:: django.template.backends
 | |
| 
 | |
| Built-in backends
 | |
| -----------------
 | |
| 
 | |
| .. module:: django.template.backends.django
 | |
| 
 | |
| .. class:: DjangoTemplates
 | |
| 
 | |
| Set :setting:`BACKEND <TEMPLATES-BACKEND>` to
 | |
| ``'django.template.backends.django.DjangoTemplates'`` to configure a Django
 | |
| template engine.
 | |
| 
 | |
| When :setting:`APP_DIRS <TEMPLATES-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
 | |
| <TEMPLATES-OPTIONS>`:
 | |
| 
 | |
| * ``'autoescape'``: a boolean that controls whether HTML autoescaping is
 | |
|   enabled.
 | |
| 
 | |
|   It defaults to ``True``.
 | |
| 
 | |
|   .. warning::
 | |
| 
 | |
|       Only set it to ``False`` if you're rendering non-HTML templates!
 | |
| 
 | |
|   .. versionadded:: 1.10
 | |
| 
 | |
|       The ``autoescape`` option was added.
 | |
| 
 | |
| * ``'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:`DEBUG` setting.
 | |
| 
 | |
| * ``'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 <TEMPLATES-DIRS>` and
 | |
|   :setting:`APP_DIRS <TEMPLATES-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`.
 | |
| 
 | |
| * ``'libraries'``: A dictionary of labels and dotted Python paths of template
 | |
|   tag modules to register with the template engine. This can be used to add
 | |
|   new libraries or provide alternate labels for existing ones. For example::
 | |
| 
 | |
|       OPTIONS={
 | |
|           'libraries': {
 | |
|               'myapp_tags': 'path.to.myapp.tags',
 | |
|               'admin.urls': 'django.contrib.admin.templatetags.admin_urls',
 | |
|           },
 | |
|       }
 | |
| 
 | |
|   Libraries can be loaded by passing the corresponding dictionary key to
 | |
|   the :ttag:`{% load %}<load>` tag.
 | |
| 
 | |
| * ``'builtins'``: A list of dotted Python paths of template tag modules to
 | |
|   add to :doc:`built-ins </ref/templates/builtins>`. For example::
 | |
| 
 | |
|       OPTIONS={
 | |
|           'builtins': ['myapp.builtins'],
 | |
|       }
 | |
| 
 | |
|   Tags and filters from built-in libraries can be used without first calling
 | |
|   the :ttag:`{% load %} <load>` tag.
 | |
| 
 | |
| .. module:: django.template.backends.jinja2
 | |
| 
 | |
| .. class:: Jinja2
 | |
| 
 | |
| Requires Jinja2_ to be installed:
 | |
| 
 | |
| .. code-block:: console
 | |
| 
 | |
|     $ pip install Jinja2
 | |
| 
 | |
| Set :setting:`BACKEND <TEMPLATES-BACKEND>` to
 | |
| ``'django.template.backends.jinja2.Jinja2'`` to configure a Jinja2_ engine.
 | |
| 
 | |
| When :setting:`APP_DIRS <TEMPLATES-APP_DIRS>` is ``True``, ``Jinja2`` engines
 | |
| look for templates in the ``jinja2`` subdirectory of installed applications.
 | |
| 
 | |
| The most important entry in :setting:`OPTIONS <TEMPLATES-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 <TEMPLATES-DIRS>` and
 | |
|   :setting:`APP_DIRS <TEMPLATES-APP_DIRS>`
 | |
| * ``'auto_reload'``: ``settings.DEBUG``
 | |
| * ``'undefined'``: ``DebugUndefined if settings.DEBUG else Undefined``
 | |
| 
 | |
| ``Jinja2`` engines also accept the following :setting:`OPTIONS
 | |
| <TEMPLATES-OPTIONS>`:
 | |
| 
 | |
| * ``'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.
 | |
| 
 | |
| .. versionadded:: 1.11
 | |
| 
 | |
|     The ``'context_processors'`` option was added.
 | |
| 
 | |
| The default configuration is purposefully kept to a minimum. If a template is
 | |
| rendered with a request (e.g. when using :py:func:`~django.shortcuts.render`),
 | |
| the ``Jinja2`` backend adds the globals ``request``, ``csrf_input``, and
 | |
| ``csrf_token`` to the context. Apart from that, this backend doesn't create a
 | |
| Django-flavored environment. It doesn't know about Django filters and tags.
 | |
| In order to use Django-specific APIs, you must configure them into the
 | |
| environment.
 | |
| 
 | |
| For example, you can create ``myproject/jinja2.py`` with this content::
 | |
| 
 | |
|     from __future__ import absolute_import  # Python 2 only
 | |
| 
 | |
|     from django.contrib.staticfiles.storage import staticfiles_storage
 | |
|     from django.urls import reverse
 | |
| 
 | |
|     from jinja2 import Environment
 | |
| 
 | |
| 
 | |
|     def environment(**options):
 | |
|         env = Environment(**options)
 | |
|         env.globals.update({
 | |
|             'static': staticfiles_storage.url,
 | |
|             'url': reverse,
 | |
|         })
 | |
|         return env
 | |
| 
 | |
| and set the ``'environment'`` option to ``'myproject.jinja2.environment'``.
 | |
| 
 | |
| Then you could use the following constructs in Jinja2 templates:
 | |
| 
 | |
| .. code-block:: html+jinja
 | |
| 
 | |
|     <img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">
 | |
| 
 | |
|     <a href="{{ url('admin:index') }}">Administration</a>
 | |
| 
 | |
| The concepts of tags and filters exist both in the Django template language
 | |
| and in Jinja2 but they're used differently. Since Jinja2 supports passing
 | |
| arguments to callables in templates, many features that require a template tag
 | |
| or filter in Django templates can be achieved simply by calling a function in
 | |
| Jinja2 templates, as shown in the example above. Jinja2's global namespace
 | |
| removes the need for template context processors. The Django template language
 | |
| doesn't have an equivalent of Jinja2 tests.
 | |
| 
 | |
| 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, backend=self)
 | |
|             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.
 | |
| 
 | |
| .. _template-debug-integration:
 | |
| 
 | |
| Debug integration for custom engines
 | |
| ------------------------------------
 | |
| 
 | |
| The Django debug page has hooks to provide detailed information when a template
 | |
| error arises. Custom template engines can use these hooks to enhance the
 | |
| traceback information that appears to users. The following hooks are available:
 | |
| 
 | |
| .. _template-postmortem:
 | |
| 
 | |
| Template postmortem
 | |
| ~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| The postmortem appears when :exc:`~django.template.TemplateDoesNotExist` is
 | |
| raised. It lists the template engines and loaders that were used when trying
 | |
| to find a given template. For example, if two Django engines are configured,
 | |
| the postmortem will appear like:
 | |
| 
 | |
| .. image:: _images/postmortem.png
 | |
| 
 | |
| Custom engines can populate the postmortem by passing the ``backend`` and
 | |
| ``tried`` arguments when raising :exc:`~django.template.TemplateDoesNotExist`.
 | |
| Backends that use the postmortem :ref:`should specify an origin
 | |
| <template-origin-api>` on the template object.
 | |
| 
 | |
| Contextual line information
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| If an error happens during template parsing or rendering, Django can display
 | |
| the line the error happened on. For example:
 | |
| 
 | |
| .. image:: _images/template-lines.png
 | |
| 
 | |
| Custom engines can populate this information by setting a ``template_debug``
 | |
| attribute on exceptions raised during parsing and rendering. This attribute
 | |
| is a :class:`dict` with the following values:
 | |
| 
 | |
| * ``'name'``: The name of the template in which the exception occurred.
 | |
| 
 | |
| * ``'message'``: The exception message.
 | |
| 
 | |
| * ``'source_lines'``: The lines before, after, and including the line the
 | |
|   exception occurred on. This is for context, so it shouldn't contain more than
 | |
|   20 lines or so.
 | |
| 
 | |
| * ``'line'``: The line number on which the exception occurred.
 | |
| 
 | |
| * ``'before'``: The content on the error line before the token that raised the
 | |
|   error.
 | |
| 
 | |
| * ``'during'``: The token that raised the error.
 | |
| 
 | |
| * ``'after'``: The content on the error line after the token that raised the
 | |
|   error.
 | |
| 
 | |
| * ``'total'``: The number of lines in ``source_lines``.
 | |
| 
 | |
| * ``'top'``: The line number where ``source_lines`` starts.
 | |
| 
 | |
| * ``'bottom'``: The line number where ``source_lines`` ends.
 | |
| 
 | |
| Given the above template error, ``template_debug`` would look like::
 | |
| 
 | |
|     {
 | |
|         'name': '/path/to/template.html',
 | |
|         'message': "Invalid block tag: 'syntax'",
 | |
|         'source_lines': [
 | |
|             (1, 'some\n'),
 | |
|             (2, 'lines\n'),
 | |
|             (3, 'before\n'),
 | |
|             (4, 'Hello {% syntax error %} {{ world }}\n'),
 | |
|             (5, 'some\n'),
 | |
|             (6, 'lines\n'),
 | |
|             (7, 'after\n'),
 | |
|             (8, ''),
 | |
|         ],
 | |
|         'line': 4,
 | |
|         'before': 'Hello ',
 | |
|         'during': '{% syntax error %}',
 | |
|         'after': ' {{ world }}\n',
 | |
|         'total': 9,
 | |
|         'bottom': 9,
 | |
|         'top': 1,
 | |
|     }
 | |
| 
 | |
| .. _template-origin-api:
 | |
| 
 | |
| Origin API and 3rd-party integration
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Django templates have an :class:`~django.template.base.Origin` object available
 | |
| through the ``template.origin`` attribute. This enables debug information to be
 | |
| displayed in the :ref:`template postmortem <template-postmortem>`, as well as
 | |
| in 3rd-party libraries, like the `Django Debug Toolbar`_.
 | |
| 
 | |
| Custom engines can provide their own ``template.origin`` information by
 | |
| creating an object that specifies the following attributes:
 | |
| 
 | |
| * ``'name'``: The full path to the template.
 | |
| 
 | |
| * ``'template_name'``: The relative path to the template as passed into the
 | |
|   the template loading methods.
 | |
| 
 | |
| * ``'loader_name'``: An optional string identifying the function or class used
 | |
|   to load the template, e.g. ``django.template.loaders.filesystem.Loader``.
 | |
| 
 | |
| .. 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 </ref/templates/language>`.
 | |
| 
 | |
| 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 <ref-templates-builtins-tags>` is
 | |
| available as well as :ref:`instructions for writing custom tags
 | |
| <howto-writing-custom-template-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 <ref-templates-builtins-filters>` is
 | |
| available as well as :ref:`instructions for writing custom filters
 | |
| <howto-writing-custom-template-filters>`.
 | |
| 
 | |
| Comments
 | |
| ~~~~~~~~
 | |
| 
 | |
| Comments look like this::
 | |
| 
 | |
|     {# this won't be rendered #}
 | |
| 
 | |
| A :ttag:`{% comment %} <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 </ref/templates/api>`.
 | |
| 
 | |
| 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()
 | |
| <django.template.Engine.get_template>` or :meth:`Engine.from_string()
 | |
| <django.template.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()
 | |
| <django.template.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 <template-loaders>`
 | |
| and supports :ref:`custom template loaders <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 <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/final/0182-multiple-template-engines.rst
 | |
| .. _Django Debug Toolbar: https://github.com/django-debug-toolbar/django-debug-toolbar
 |