Documented the simple_tag and inclusion_tag functions that make writing certain
types of template tags easier. git-svn-id: http://code.djangoproject.com/svn/django/trunk@2941 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
e6ee971498
commit
026d8c6f08
|
@ -743,6 +743,164 @@ Python 2.4 and above::
|
||||||
If you leave off the ``name`` argument, as in the second example above, Django
|
If you leave off the ``name`` argument, as in the second example above, Django
|
||||||
will use the function's name as the tag name.
|
will use the function's name as the tag name.
|
||||||
|
|
||||||
|
Shortcut for simple tags
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Many template tags take a single argument -- a string or a template variable
|
||||||
|
reference -- and return a string after doing some processing based solely on
|
||||||
|
the input argument and some external information. For example, the
|
||||||
|
``current_time`` tag we wrote above is of this variety: we give it a format
|
||||||
|
string, it returns the time as a string.
|
||||||
|
|
||||||
|
To ease the creation of the types of tags, Django provides a helper function,
|
||||||
|
``simple_tag``. This function, which is a method of
|
||||||
|
``django.template.Library``, takes a function that accepts one argument, wraps
|
||||||
|
it in a ``render`` function and the other necessary bits mentioned above and
|
||||||
|
registers it with the template system.
|
||||||
|
|
||||||
|
Our earlier ``current_time`` function could thus be written like this::
|
||||||
|
|
||||||
|
# This version of do_current_time takes only a single argument and returns
|
||||||
|
# a string.
|
||||||
|
|
||||||
|
def do_current_time(token):
|
||||||
|
try:
|
||||||
|
# Splitting by None == splitting by spaces.
|
||||||
|
tag_name, format_string = token.contents.split(None, 1)
|
||||||
|
except ValueError:
|
||||||
|
raise template.TemplateSyntaxError, "%r tag requires an argument" % token.contents[0]
|
||||||
|
if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
|
||||||
|
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
|
||||||
|
return datetime.datetime.now().strftime(self.format_string[1:-1])
|
||||||
|
|
||||||
|
register.simple_tag(do_current_time)
|
||||||
|
|
||||||
|
In Python 2.4, the decorator syntax also works::
|
||||||
|
|
||||||
|
@simple_tag
|
||||||
|
def do_current_time(token):
|
||||||
|
...
|
||||||
|
|
||||||
|
Inclusion tags
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Another type of template tag that is sometimes useful is when you want to
|
||||||
|
display some data that is computed at render time in a template fragment. For
|
||||||
|
example, in Django's admin interface, there is a line of buttons along the
|
||||||
|
bottom of the `create/edit record` screen. These buttons always look the same,
|
||||||
|
but the link targets change depending upon the object being edited. So they
|
||||||
|
are a perfect example for using a small template that is filled in with
|
||||||
|
details from the current object. To save typing, it would also be nice if we
|
||||||
|
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
|
||||||
|
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
|
||||||
|
a tag that outputs a list of choices for a Poll object, such as was created in
|
||||||
|
the tutorials_. We will use this tag like this::
|
||||||
|
|
||||||
|
{{ show_results poll }}
|
||||||
|
|
||||||
|
and the output will be something like this::
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>First choice</li>
|
||||||
|
<li>Second choice</li>
|
||||||
|
<li>Third choice</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
First, we define the function which takes the argument and produces a
|
||||||
|
dictionary of data for the result. The important point here is we only need to
|
||||||
|
return a dictionary, not anything more complex. This will be used to substitue
|
||||||
|
for values in the template fragment, just as when templates are used
|
||||||
|
elsewhere.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
def show_results(poll):
|
||||||
|
choices = poll.choice_set.all()
|
||||||
|
return {'choices': choices}
|
||||||
|
|
||||||
|
We also need to create the template that is used to render the output. This
|
||||||
|
template is a fixed feature of the tag: the tag writer specifies it, not the
|
||||||
|
template designer. In our case, the template is very simple::
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for choice in choices %}
|
||||||
|
<li> {{ choice }} </li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
Now we can create the inclusion tag. Suppose the above template is in a file
|
||||||
|
called ``results.html`` in a directory that is searched by the template
|
||||||
|
loader. We register our new tag similarly to a normal tag.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Here, register is a django.template.Library instance, as before
|
||||||
|
register.inclusion_tag('results.html')(show_results)
|
||||||
|
|
||||||
|
As always, Python 2.4 decorator syntax works as well, so we could have
|
||||||
|
written
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
@inclusion_tag('results.html')
|
||||||
|
def show_results(poll):
|
||||||
|
...
|
||||||
|
|
||||||
|
when first creating the function.
|
||||||
|
|
||||||
|
In some cases, an inclusion tag might require a large number of arguments to
|
||||||
|
display itself properly. In essence, it would depend largely on the current
|
||||||
|
context it was being rendered with. We can make these sorts of tags easier to
|
||||||
|
write by telling the ``inclusion_tag`` function that the whole context
|
||||||
|
should be passed in as an argument to the function. This will be done
|
||||||
|
invisibly as far as the template tag user is concerned: they will not need to
|
||||||
|
do anything to pass in the context.
|
||||||
|
|
||||||
|
For example, suppose we are writing an inclusion tag that will always be used
|
||||||
|
in a context that contains ``home_link`` and ``home_title`` variables that
|
||||||
|
point back to the main page. We can write a tag that is used like this::
|
||||||
|
|
||||||
|
{{ 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.
|
||||||
|
def jump_link(context):
|
||||||
|
return {
|
||||||
|
'link': context['home_link'],
|
||||||
|
'title': context['home_title'],
|
||||||
|
}
|
||||||
|
|
||||||
|
Our template is very simple again::
|
||||||
|
|
||||||
|
Jump directly to <a href="{{ link }}">{{ title }}</a>.
|
||||||
|
|
||||||
|
Assuming the template is in a file called ``link.html``, we register this new
|
||||||
|
tag as follows::
|
||||||
|
|
||||||
|
register.inclusion_tag('link.html', takes_context = True)(jump_link)
|
||||||
|
|
||||||
|
The ``takes_context`` parameter here defaults to *False*. When it is set to
|
||||||
|
*True*, our tag is passed the implicit context as in this example. That is the
|
||||||
|
only difference between this case and our previous use of ``inclusion_tag``.
|
||||||
|
|
||||||
|
.. _tutorials: http://www.djangoproject.com/documentation/tutorial1/#creating-models
|
||||||
|
|
||||||
Setting a variable in the context
|
Setting a variable in the context
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue