1
0
mirror of https://github.com/django/django.git synced 2024-12-23 17:46:27 +00:00
django/docs/topics/templates.txt
2015-02-01 21:02:40 -05:00

645 lines
22 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
============================
.. 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 <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[, 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 <TEMPLATES-NAME>` in the ``using`` argument.
.. 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.
.. 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 <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>`:
* ``'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 <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`.
.. module:: django.template.backends.jinja2
.. class:: 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``
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 </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/accepted/0182-multiple-template-engines.rst