mirror of https://github.com/django/django.git
Made some edits to docs/templates_python.txt 'inclusion_tag' section
git-svn-id: http://code.djangoproject.com/svn/django/trunk@2979 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
b631a50250
commit
14392b032d
|
@ -784,27 +784,23 @@ In Python 2.4, the decorator syntax also works::
|
||||||
Inclusion tags
|
Inclusion tags
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Another type of template tag that is sometimes useful is when you want to
|
Another common type of template tag is the type that displays some data by
|
||||||
display some data that is computed at render time in a template fragment. For
|
rendering *another* template. For example, Django's admin interface uses custom
|
||||||
example, in Django's admin interface, there is a line of buttons along the
|
template tags to display the buttons along the botton of the "add/change" form
|
||||||
bottom of the `create/edit record` screen. These buttons always look the same,
|
pages. Those buttons always look the same, but the link targets change depending
|
||||||
but the link targets change depending upon the object being edited. So they
|
on the object being edited -- so they're a perfect case for using a small
|
||||||
are a perfect example for using a small template that is filled in with
|
template that is filled with details from the current object. (In the admin's
|
||||||
details from the current object. To save typing, it would also be nice if we
|
case, this is the ``submit_row`` tag.)
|
||||||
could wrap this whole display up in a single tag (in the admin templates this
|
|
||||||
is the ``submit_row`` tag).
|
|
||||||
|
|
||||||
We call these sorts of tags `inclusion tags`. In your template, you pass in
|
These sorts of tags are called `inclusion tags`.
|
||||||
any appropriate arguments and the tag uses those arguments, together with the
|
|
||||||
current context to render a template and include the result in the output.
|
|
||||||
|
|
||||||
Writing inclusion tags is probably best demonstrated by example. We will write
|
Writing inclusion tags is probably best demonstrated by example. Let's write a
|
||||||
a tag that outputs a list of choices for a Poll object, such as was created in
|
tag that outputs a list of choices for a given ``Poll`` object, such as was
|
||||||
the tutorials_. We will use this tag like this::
|
created in the tutorials_. We'll use the tag like this::
|
||||||
|
|
||||||
{% show_results poll %}
|
{% show_results poll %}
|
||||||
|
|
||||||
and the output will be something like this::
|
...and the output will be something like this::
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>First choice</li>
|
<li>First choice</li>
|
||||||
|
@ -812,21 +808,18 @@ and the output will be something like this::
|
||||||
<li>Third choice</li>
|
<li>Third choice</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
First, we define the function which takes the argument and produces a
|
First, define the function that takes the argument and produces a dictionary of
|
||||||
dictionary of data for the result. The important point here is we only need to
|
data for the result. The important point here is we only need to return a
|
||||||
return a dictionary, not anything more complex. This will be used to substitue
|
dictionary, not anything more complex. This will be used as a template context
|
||||||
for values in the template fragment, just as when templates are used
|
for the template fragment. Example::
|
||||||
elsewhere.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
def show_results(poll):
|
def show_results(poll):
|
||||||
choices = poll.choice_set.all()
|
choices = poll.choice_set.all()
|
||||||
return {'choices': choices}
|
return {'choices': choices}
|
||||||
|
|
||||||
We also need to create the template that is used to render the output. This
|
Next, create the template used to render the tag's output. This template is a
|
||||||
template is a fixed feature of the tag: the tag writer specifies it, not the
|
fixed feature of the tag: the tag writer specifies it, not the template
|
||||||
template designer. In our case, the template is very simple::
|
designer. Following our example, the template is very simple::
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{% for choice in choices %}
|
{% for choice in choices %}
|
||||||
|
@ -834,50 +827,33 @@ template designer. In our case, the template is very simple::
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Now we can create the inclusion tag. Suppose the above template is in a file
|
Now, create and register the inclusion tag by calling the ``inclusion_tag()``
|
||||||
called ``results.html`` in a directory that is searched by the template
|
method on a ``Library`` object. Following our example, if the above template is
|
||||||
loader. We register our new tag similarly to a normal tag.
|
in a file called ``results.html`` in a directory that's searched by the template
|
||||||
|
loader, we'd register the tag like this::
|
||||||
::
|
|
||||||
|
|
||||||
# Here, register is a django.template.Library instance, as before
|
# Here, register is a django.template.Library instance, as before
|
||||||
register.inclusion_tag('results.html')(show_results)
|
register.inclusion_tag('results.html')(show_results)
|
||||||
|
|
||||||
As always, Python 2.4 decorator syntax works as well, so we could have
|
As always, Python 2.4 decorator syntax works as well, so we could have
|
||||||
written
|
written::
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
@inclusion_tag('results.html')
|
@inclusion_tag('results.html')
|
||||||
def show_results(poll):
|
def show_results(poll):
|
||||||
...
|
...
|
||||||
|
|
||||||
when first creating the function.
|
...when first creating the function.
|
||||||
|
|
||||||
In some cases, an inclusion tag might require a large number of arguments to
|
Sometimes, your inclusion tags might require a large number of arguments,
|
||||||
display itself properly. In essence, it would depend largely on the current
|
making it a pain for template authors to pass in all the arguments and remember
|
||||||
context it was being rendered with. We can make these sorts of tags easier to
|
their order. To solve this, Django provides a ``takes_context`` option for
|
||||||
write by telling the ``inclusion_tag`` function that the whole context
|
inclusion tags. If you specify ``takes_context`` in creating a template tag,
|
||||||
should be passed in as an argument to the function. This will be done
|
the tag will have no required arguments, and the underlying Python function
|
||||||
invisibly as far as the template tag user is concerned: they will not need to
|
will have one argument -- the template context as of when the tag was called.
|
||||||
do anything to pass in the context.
|
|
||||||
|
|
||||||
For example, suppose we are writing an inclusion tag that will always be used
|
For example, say you're writing an inclusion tag that will always be used in a
|
||||||
in a context that contains ``home_link`` and ``home_title`` variables that
|
context that contains ``home_link`` and ``home_title`` variables that point
|
||||||
point back to the main page. We can write a tag that is used like this::
|
back to the main page. Here's what the Python function would look like::
|
||||||
|
|
||||||
{% jump_link %}
|
|
||||||
|
|
||||||
and renders this::
|
|
||||||
|
|
||||||
Jump directly to <a href="http://example.com/home">Home</a>
|
|
||||||
|
|
||||||
The tag function is almost as simple as before. This time it takes no
|
|
||||||
arguments except the ``context`` (and the parameter `must` be called
|
|
||||||
``context`` in this case; the special parameter named is used internally by
|
|
||||||
Django to fill in the values correctly).
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# The first argument *must* be called "context" here.
|
# The first argument *must* be called "context" here.
|
||||||
def jump_link(context):
|
def jump_link(context):
|
||||||
|
@ -885,19 +861,28 @@ Django to fill in the values correctly).
|
||||||
'link': context['home_link'],
|
'link': context['home_link'],
|
||||||
'title': context['home_title'],
|
'title': context['home_title'],
|
||||||
}
|
}
|
||||||
|
# Register the custom tag as an inclusion tag with takes_context=True.
|
||||||
|
register.inclusion_tag('link.html', takes_context=True)(jump_link)
|
||||||
|
|
||||||
Our template is very simple again::
|
(Note that the first parameter to the function *must* be called ``context``.)
|
||||||
|
|
||||||
|
In that ``register.inclusion_tag()`` line, we specified ``takes_context=True``
|
||||||
|
and the name of the template. Here's what the template ``link.html`` might look
|
||||||
|
like::
|
||||||
|
|
||||||
Jump directly to <a href="{{ link }}">{{ title }}</a>.
|
Jump directly to <a href="{{ link }}">{{ title }}</a>.
|
||||||
|
|
||||||
Assuming the template is in a file called ``link.html``, we register this new
|
Then, any time you want to use that custom tag, load its library and call it
|
||||||
tag as follows::
|
without any arguments, like so::
|
||||||
|
|
||||||
register.inclusion_tag('link.html', takes_context = True)(jump_link)
|
{% jump_link %}
|
||||||
|
|
||||||
The ``takes_context`` parameter here defaults to *False*. When it is set to
|
Note that when you're using ``takes_context=True``, there's no need to pass
|
||||||
*True*, our tag is passed the implicit context as in this example. That is the
|
arguments to the template tag. It automatically gets access to the context.
|
||||||
only difference between this case and our previous use of ``inclusion_tag``.
|
|
||||||
|
The ``takes_context`` parameter defaults to ``False``. When it's set to *True*,
|
||||||
|
the tag is passed the context object, as in this example. That's the only
|
||||||
|
difference between this case and the previous ``inclusion_tag`` example.
|
||||||
|
|
||||||
.. _tutorials: http://www.djangoproject.com/documentation/tutorial1/#creating-models
|
.. _tutorials: http://www.djangoproject.com/documentation/tutorial1/#creating-models
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue