Add Django-1.2.1
[frozenviper.git] / Django-1.2.1 / docs / howto / custom-template-tags.txt
blob1406d19b588f594bef2154d58ce449bd1c559e0c
1 .. _howto-custom-template-tags:
3 ================================
4 Custom template tags and filters
5 ================================
7 Introduction
8 ============
10 Django's template system comes with a wide variety of :ref:`built-in
11 tags and filters <ref-templates-builtins>` designed to address the
12 presentation logic needs of your application. Nevertheless, you may
13 find yourself needing functionality that is not covered by the core
14 set of template primitives. You can extend the template engine by
15 defining custom tags and filters using Python, and then make them
16 available to your templates using the ``{% load %}`` tag.
18 Code layout
19 -----------
21 Custom template tags and filters must live inside a Django app. If they relate
22 to an existing app it makes sense to bundle them there; otherwise, you should
23 create a new app to hold them.
25 The app should contain a ``templatetags`` directory, at the same level as
26 ``models.py``, ``views.py``, etc. If this doesn't already exist, create it -
27 don't forget the ``__init__.py`` file to ensure the directory is treated as a
28 Python package.
30 Your custom tags and filters will live in a module inside the ``templatetags``
31 directory. The name of the module file is the name you'll use to load the tags
32 later, so be careful to pick a name that won't clash with custom tags and
33 filters in another app.
35 For example, if your custom tags/filters are in a file called
36 ``poll_extras.py``, your app layout might look like this::
38     polls/
39         models.py
40         templatetags/
41             __init__.py
42             poll_extras.py
43         views.py
45 And in your template you would use the following:
47 .. code-block:: html+django
49     {% load poll_extras %}
51 The app that contains the custom tags must be in :setting:`INSTALLED_APPS` in
52 order for the ``{% load %}`` tag to work. This is a security feature: It allows
53 you to host Python code for many template libraries on a single host machine
54 without enabling access to all of them for every Django installation.
56 There's no limit on how many modules you put in the ``templatetags`` package.
57 Just keep in mind that a ``{% load %}`` statement will load tags/filters for
58 the given Python module name, not the name of the app.
60 To be a valid tag library, the module must contain a module-level variable
61 named ``register`` that is a ``template.Library`` instance, in which all the
62 tags and filters are registered. So, near the top of your module, put the
63 following::
65     from django import template
67     register = template.Library()
69 .. admonition:: Behind the scenes
71     For a ton of examples, read the source code for Django's default filters
72     and tags. They're in ``django/template/defaultfilters.py`` and
73     ``django/template/defaulttags.py``, respectively.
75 Writing custom template filters
76 -------------------------------
78 Custom filters are just Python functions that take one or two arguments:
80     * The value of the variable (input) -- not necessarily a string.
81     * The value of the argument -- this can have a default value, or be left
82       out altogether.
84 For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
85 passed the variable ``var`` and the argument ``"bar"``.
87 Filter functions should always return something. They shouldn't raise
88 exceptions. They should fail silently. In case of error, they should return
89 either the original input or an empty string -- whichever makes more sense.
91 Here's an example filter definition::
93     def cut(value, arg):
94         "Removes all values of arg from the given string"
95         return value.replace(arg, '')
97 And here's an example of how that filter would be used:
99 .. code-block:: html+django
101     {{ somevariable|cut:"0" }}
103 Most filters don't take arguments. In this case, just leave the argument out of
104 your function. Example::
106     def lower(value): # Only one argument.
107         "Converts a string into all lowercase"
108         return value.lower()
110 Template filters that expect strings
111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113 If you're writing a template filter that only expects a string as the first
114 argument, you should use the decorator ``stringfilter``. This will
115 convert an object to its string value before being passed to your function::
117     from django.template.defaultfilters import stringfilter
119     @stringfilter
120     def lower(value):
121         return value.lower()
123 This way, you'll be able to pass, say, an integer to this filter, and it
124 won't cause an ``AttributeError`` (because integers don't have ``lower()``
125 methods).
127 Registering custom filters
128 ~~~~~~~~~~~~~~~~~~~~~~~~~~
130 Once you've written your filter definition, you need to register it with
131 your ``Library`` instance, to make it available to Django's template language::
133     register.filter('cut', cut)
134     register.filter('lower', lower)
136 The ``Library.filter()`` method takes two arguments:
138     1. The name of the filter -- a string.
139     2. The compilation function -- a Python function (not the name of the
140        function as a string).
142 You can use ``register.filter()`` as a decorator instead::
144     @register.filter(name='cut')
145     @stringfilter
146     def cut(value, arg):
147         return value.replace(arg, '')
149     @register.filter
150     @stringfilter
151     def lower(value):
152         return value.lower()
154 If you leave off the ``name`` argument, as in the second example above, Django
155 will use the function's name as the filter name.
157 Filters and auto-escaping
158 ~~~~~~~~~~~~~~~~~~~~~~~~~
160 .. versionadded:: 1.0
162 When writing a custom filter, give some thought to how the filter will interact
163 with Django's auto-escaping behavior. Note that three types of strings can be
164 passed around inside the template code:
166     * **Raw strings** are the native Python ``str`` or ``unicode`` types. On
167       output, they're escaped if auto-escaping is in effect and presented
168       unchanged, otherwise.
170     * **Safe strings** are strings that have been marked safe from further
171       escaping at output time. Any necessary escaping has already been done.
172       They're commonly used for output that contains raw HTML that is intended
173       to be interpreted as-is on the client side.
175       Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
176       They share a common base class of ``SafeData``, so you can test
177       for them using code like::
179           if isinstance(value, SafeData):
180               # Do something with the "safe" string.
182     * **Strings marked as "needing escaping"** are *always* escaped on
183       output, regardless of whether they are in an ``autoescape`` block or not.
184       These strings are only escaped once, however, even if auto-escaping
185       applies.
187       Internally, these strings are of type ``EscapeString`` or
188       ``EscapeUnicode``. Generally you don't have to worry about these; they
189       exist for the implementation of the ``escape`` filter.
191 Template filter code falls into one of two situations:
193     1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
194        ``'``, ``"`` or ``&``) into the result that were not already present. In
195        this case, you can let Django take care of all the auto-escaping
196        handling for you. All you need to do is put the ``is_safe`` attribute on
197        your filter function and set it to ``True``, like so::
199            @register.filter
200            def myfilter(value):
201                return value
202            myfilter.is_safe = True
204        This attribute tells Django that if a "safe" string is passed into your
205        filter, the result will still be "safe" and if a non-safe string is
206        passed in, Django will automatically escape it, if necessary.
208        You can think of this as meaning "this filter is safe -- it doesn't
209        introduce any possibility of unsafe HTML."
211        The reason ``is_safe`` is necessary is because there are plenty of
212        normal string operations that will turn a ``SafeData`` object back into
213        a normal ``str`` or ``unicode`` object and, rather than try to catch
214        them all, which would be very difficult, Django repairs the damage after
215        the filter has completed.
217        For example, suppose you have a filter that adds the string ``xx`` to the
218        end of any input. Since this introduces no dangerous HTML characters to
219        the result (aside from any that were already present), you should mark
220        your filter with ``is_safe``::
222            @register.filter
223            def add_xx(value):
224                return '%sxx' % value
225            add_xx.is_safe = True
227        When this filter is used in a template where auto-escaping is enabled,
228        Django will escape the output whenever the input is not already marked as
229        "safe".
231        By default, ``is_safe`` defaults to ``False``, and you can omit it from
232        any filters where it isn't required.
234        Be careful when deciding if your filter really does leave safe strings
235        as safe. If you're *removing* characters, you might inadvertently leave
236        unbalanced HTML tags or entities in the result. For example, removing a
237        ``>`` from the input might turn ``<a>`` into ``<a``, which would need to
238        be escaped on output to avoid causing problems. Similarly, removing a
239        semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
240        valid entity and thus needs further escaping. Most cases won't be nearly
241        this tricky, but keep an eye out for any problems like that when
242        reviewing your code.
244        Marking a filter ``is_safe`` will coerce the filter's return value to
245        a string.  If your filter should return a boolean or other non-string
246        value, marking it ``is_safe`` will probably have unintended
247        consequences (such as converting a boolean False to the string
248        'False').
250     2. Alternatively, your filter code can manually take care of any necessary
251        escaping. This is necessary when you're introducing new HTML markup into
252        the result. You want to mark the output as safe from further
253        escaping so that your HTML markup isn't escaped further, so you'll need
254        to handle the input yourself.
256        To mark the output as a safe string, use
257        :func:`django.utils.safestring.mark_safe`.
259        Be careful, though. You need to do more than just mark the output as
260        safe. You need to ensure it really *is* safe, and what you do depends on
261        whether auto-escaping is in effect. The idea is to write filters than
262        can operate in templates where auto-escaping is either on or off in
263        order to make things easier for your template authors.
265        In order for your filter to know the current auto-escaping state, set
266        the ``needs_autoescape`` attribute to ``True`` on your function. (If you
267        don't specify this attribute, it defaults to ``False``). This attribute
268        tells Django that your filter function wants to be passed an extra
269        keyword argument, called ``autoescape``, that is ``True`` if
270        auto-escaping is in effect and ``False`` otherwise.
272        For example, let's write a filter that emphasizes the first character of
273        a string::
275            from django.utils.html import conditional_escape
276            from django.utils.safestring import mark_safe
278            def initial_letter_filter(text, autoescape=None):
279                first, other = text[0], text[1:]
280                if autoescape:
281                    esc = conditional_escape
282                else:
283                    esc = lambda x: x
284                result = '<strong>%s</strong>%s' % (esc(first), esc(other))
285                return mark_safe(result)
286            initial_letter_filter.needs_autoescape = True
288        The ``needs_autoescape`` attribute on the filter function and the
289        ``autoescape`` keyword argument mean that our function will know whether
290        automatic escaping is in effect when the filter is called. We use
291        ``autoescape`` to decide whether the input data needs to be passed
292        through ``django.utils.html.conditional_escape`` or not. (In the latter
293        case, we just use the identity function as the "escape" function.) The
294        ``conditional_escape()`` function is like ``escape()`` except it only
295        escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
296        instance is passed to ``conditional_escape()``, the data is returned
297        unchanged.
299        Finally, in the above example, we remember to mark the result as safe
300        so that our HTML is inserted directly into the template without further
301        escaping.
303        There's no need to worry about the ``is_safe`` attribute in this case
304        (although including it wouldn't hurt anything). Whenever you manually
305        handle the auto-escaping issues and return a safe string, the
306        ``is_safe`` attribute won't change anything either way.
308 Writing custom template tags
309 ----------------------------
311 Tags are more complex than filters, because tags can do anything.
313 A quick overview
314 ~~~~~~~~~~~~~~~~
316 Above, this document explained that the template system works in a two-step
317 process: compiling and rendering. To define a custom template tag, you specify
318 how the compilation works and how the rendering works.
320 When Django compiles a template, it splits the raw template text into
321 ''nodes''. Each node is an instance of ``django.template.Node`` and has
322 a ``render()`` method. A compiled template is, simply, a list of ``Node``
323 objects. When you call ``render()`` on a compiled template object, the template
324 calls ``render()`` on each ``Node`` in its node list, with the given context.
325 The results are all concatenated together to form the output of the template.
327 Thus, to define a custom template tag, you specify how the raw template tag is
328 converted into a ``Node`` (the compilation function), and what the node's
329 ``render()`` method does.
331 Writing the compilation function
332 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
334 For each template tag the template parser encounters, it calls a Python
335 function with the tag contents and the parser object itself. This function is
336 responsible for returning a ``Node`` instance based on the contents of the tag.
338 For example, let's write a template tag, ``{% current_time %}``, that displays
339 the current date/time, formatted according to a parameter given in the tag, in
340 `strftime syntax`_. It's a good idea to decide the tag syntax before anything
341 else. In our case, let's say the tag should be used like this:
343 .. code-block:: html+django
345     <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
347 .. _`strftime syntax`: http://docs.python.org/library/time.html#time.strftime
349 The parser for this function should grab the parameter and create a ``Node``
350 object::
352     from django import template
353     def do_current_time(parser, token):
354         try:
355             # split_contents() knows not to split quoted strings.
356             tag_name, format_string = token.split_contents()
357         except ValueError:
358             raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
359         if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
360             raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
361         return CurrentTimeNode(format_string[1:-1])
363 Notes:
365     * ``parser`` is the template parser object. We don't need it in this
366       example.
368     * ``token.contents`` is a string of the raw contents of the tag. In our
369       example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
371     * The ``token.split_contents()`` method separates the arguments on spaces
372       while keeping quoted strings together. The more straightforward
373       ``token.contents.split()`` wouldn't be as robust, as it would naively
374       split on *all* spaces, including those within quoted strings. It's a good
375       idea to always use ``token.split_contents()``.
377     * This function is responsible for raising
378       ``django.template.TemplateSyntaxError``, with helpful messages, for
379       any syntax error.
381     * The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
382       Don't hard-code the tag's name in your error messages, because that
383       couples the tag's name to your function. ``token.contents.split()[0]``
384       will ''always'' be the name of your tag -- even when the tag has no
385       arguments.
387     * The function returns a ``CurrentTimeNode`` with everything the node needs
388       to know about this tag. In this case, it just passes the argument --
389       ``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
390       template tag are removed in ``format_string[1:-1]``.
392     * The parsing is very low-level. The Django developers have experimented
393       with writing small frameworks on top of this parsing system, using
394       techniques such as EBNF grammars, but those experiments made the template
395       engine too slow. It's low-level because that's fastest.
397 Writing the renderer
398 ~~~~~~~~~~~~~~~~~~~~
400 The second step in writing custom tags is to define a ``Node`` subclass that
401 has a ``render()`` method.
403 Continuing the above example, we need to define ``CurrentTimeNode``::
405     from django import template
406     import datetime
407     class CurrentTimeNode(template.Node):
408         def __init__(self, format_string):
409             self.format_string = format_string
410         def render(self, context):
411             return datetime.datetime.now().strftime(self.format_string)
413 Notes:
415     * ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
416       Always pass any options/parameters/arguments to a ``Node`` via its
417       ``__init__()``.
419     * The ``render()`` method is where the work actually happens.
421     * ``render()`` should never raise ``TemplateSyntaxError`` or any other
422       exception. It should fail silently, just as template filters should.
424 Ultimately, this decoupling of compilation and rendering results in an
425 efficient template system, because a template can render multiple contexts
426 without having to be parsed multiple times.
428 Auto-escaping considerations
429 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
431 .. versionadded:: 1.0
433 The output from template tags is **not** automatically run through the
434 auto-escaping filters. However, there are still a couple of things you should
435 keep in mind when writing a template tag.
437 If the ``render()`` function of your template stores the result in a context
438 variable (rather than returning the result in a string), it should take care
439 to call ``mark_safe()`` if appropriate. When the variable is ultimately
440 rendered, it will be affected by the auto-escape setting in effect at the
441 time, so content that should be safe from further escaping needs to be marked
442 as such.
444 Also, if your template tag creates a new context for performing some
445 sub-rendering, set the auto-escape attribute to the current context's value.
446 The ``__init__`` method for the ``Context`` class takes a parameter called
447 ``autoescape`` that you can use for this purpose. For example::
449     def render(self, context):
450         # ...
451         new_context = Context({'var': obj}, autoescape=context.autoescape)
452         # ... Do something with new_context ...
454 This is not a very common situation, but it's useful if you're rendering a
455 template yourself. For example::
457     def render(self, context):
458         t = template.loader.get_template('small_fragment.html')
459         return t.render(Context({'var': obj}, autoescape=context.autoescape))
461 If we had neglected to pass in the current ``context.autoescape`` value to our
462 new ``Context`` in this example, the results would have *always* been
463 automatically escaped, which may not be the desired behavior if the template
464 tag is used inside a ``{% autoescape off %}`` block.
466 .. _template_tag_thread_safety:
468 Thread-safety considerations
469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
471 .. versionadded:: 1.2
473 Once a node is parsed, its ``render`` method may be called any number of times.
474 Since Django is sometimes run in multi-threaded environments, a single node may
475 be simultaneously rendering with different contexts in response to two separate
476 requests. Therefore, it's important to make sure your template tags are thread
477 safe.
479 To make sure your template tags are thread safe, you should never store state
480 information on the node itself. For example, Django provides a builtin ``cycle``
481 template tag that cycles among a list of given strings each time it's rendered::
483     {% for o in some_list %}
484         <tr class="{% cycle 'row1' 'row2' %}>
485             ...
486         </tr>
487     {% endfor %}
489 A naive implementation of ``CycleNode`` might look something like this::
491     class CycleNode(Node):
492         def __init__(self, cyclevars):
493             self.cycle_iter = itertools.cycle(cyclevars)
494         def render(self, context):
495             return self.cycle_iter.next()
497 But, suppose we have two templates rendering the template snippet from above at
498 the same time:
500     1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
501        returns 'row1'
502     2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
503        returns 'row2'
504     3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
505        returns 'row1'
506     4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
507        returns 'row2'
509 The CycleNode is iterating, but it's iterating globally. As far as Thread 1
510 and Thread 2 are concerned, it's always returning the same value. This is
511 obviously not what we want!
513 To address this problem, Django provides a ``render_context`` that's associated
514 with the ``context`` of the template that is currently being rendered. The
515 ``render_context`` behaves like a Python dictionary, and should be used to store
516 ``Node`` state between invocations of the ``render`` method.
518 Let's refactor our ``CycleNode`` implementation to use the ``render_context``::
520     class CycleNode(Node):
521         def __init__(self, cyclevars):
522             self.cyclevars = cyclevars
523         def render(self, context):
524             if self not in context.render_context:
525                 context.render_context[self] = itertools.cycle(self.cyclevars)
526             cycle_iter = context.render_context[self]
527             return cycle_iter.next()
529 Note that it's perfectly safe to store global information that will not change
530 throughout the life of the ``Node`` as an attribute. In the case of
531 ``CycleNode``, the ``cyclevars`` argument doesn't change after the ``Node`` is
532 instantiated, so we don't need to put it in the ``render_context``. But state
533 information that is specific to the template that is currently being rendered,
534 like the current iteration of the ``CycleNode``, should be stored in the
535 ``render_context``.
537 .. note::
538     Notice how we used ``self`` to scope the ``CycleNode`` specific information
539     within the ``render_context``. There may be multiple ``CycleNodes`` in a
540     given template, so we need to be careful not to clobber another node's state
541     information. The easiest way to do this is to always use ``self`` as the key
542     into ``render_context``. If you're keeping track of several state variables,
543     make ``render_context[self]`` a dictionary.
545 Registering the tag
546 ~~~~~~~~~~~~~~~~~~~
548 Finally, register the tag with your module's ``Library`` instance, as explained
549 in "Writing custom template filters" above. Example::
551     register.tag('current_time', do_current_time)
553 The ``tag()`` method takes two arguments:
555     1. The name of the template tag -- a string. If this is left out, the
556        name of the compilation function will be used.
557     2. The compilation function -- a Python function (not the name of the
558        function as a string).
560 As with filter registration, it is also possible to use this as a decorator::
562     @register.tag(name="current_time")
563     def do_current_time(parser, token):
564         # ...
566     @register.tag
567     def shout(parser, token):
568         # ...
570 If you leave off the ``name`` argument, as in the second example above, Django
571 will use the function's name as the tag name.
573 Passing template variables to the tag
574 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
576 Although you can pass any number of arguments to a template tag using
577 ``token.split_contents()``, the arguments are all unpacked as
578 string literals. A little more work is required in order to pass dynamic
579 content (a template variable) to a template tag as an argument.
581 While the previous examples have formatted the current time into a string and
582 returned the string, suppose you wanted to pass in a ``DateTimeField`` from an
583 object and have the template tag format that date-time:
585 .. code-block:: html+django
587     <p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p>
589 Initially, ``token.split_contents()`` will return three values:
591     1. The tag name ``format_time``.
592     2. The string "blog_entry.date_updated" (without the surrounding quotes).
593     3. The formatting string "%Y-%m-%d %I:%M %p". The return value from
594        ``split_contents()`` will include the leading and trailing quotes for
595        string literals like this.
597 Now your tag should begin to look like this::
599     from django import template
600     def do_format_time(parser, token):
601         try:
602             # split_contents() knows not to split quoted strings.
603             tag_name, date_to_be_formatted, format_string = token.split_contents()
604         except ValueError:
605             raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
606         if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
607             raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
608         return FormatTimeNode(date_to_be_formatted, format_string[1:-1])
610 .. versionchanged:: 1.0
611     Variable resolution has changed in the 1.0 release of Django. ``template.resolve_variable()``
612     has been deprecated in favor of a new ``template.Variable`` class.
614 You also have to change the renderer to retrieve the actual contents of the
615 ``date_updated`` property of the ``blog_entry`` object.  This can be
616 accomplished by using the ``Variable()`` class in ``django.template``.
618 To use the ``Variable`` class, simply instantiate it with the name of the
619 variable to be resolved, and then call ``variable.resolve(context)``. So,
620 for example::
622     class FormatTimeNode(template.Node):
623         def __init__(self, date_to_be_formatted, format_string):
624             self.date_to_be_formatted = template.Variable(date_to_be_formatted)
625             self.format_string = format_string
627         def render(self, context):
628             try:
629                 actual_date = self.date_to_be_formatted.resolve(context)
630                 return actual_date.strftime(self.format_string)
631             except template.VariableDoesNotExist:
632                 return ''
634 Variable resolution will throw a ``VariableDoesNotExist`` exception if it cannot
635 resolve the string passed to it in the current context of the page.
637 Shortcut for simple tags
638 ~~~~~~~~~~~~~~~~~~~~~~~~
640 Many template tags take a number of arguments -- strings or a template variables
641 -- and return a string after doing some processing based solely on
642 the input argument and some external information. For example, the
643 ``current_time`` tag we wrote above is of this variety: we give it a format
644 string, it returns the time as a string.
646 To ease the creation of the types of tags, Django provides a helper function,
647 ``simple_tag``. This function, which is a method of
648 ``django.template.Library``, takes a function that accepts any number of
649 arguments, wraps it in a ``render`` function and the other necessary bits
650 mentioned above and registers it with the template system.
652 Our earlier ``current_time`` function could thus be written like this::
654     def current_time(format_string):
655         return datetime.datetime.now().strftime(format_string)
657     register.simple_tag(current_time)
659 The decorator syntax also works::
661     @register.simple_tag
662     def current_time(format_string):
663         ...
665 A couple of things to note about the ``simple_tag`` helper function:
667     * Checking for the required number of arguments, etc., has already been
668       done by the time our function is called, so we don't need to do that.
669     * The quotes around the argument (if any) have already been stripped away,
670       so we just receive a plain string.
671     * If the argument was a template variable, our function is passed the
672       current value of the variable, not the variable itself.
674 When your template tag does not need access to the current context, writing a
675 function to work with the input values and using the ``simple_tag`` helper is
676 the easiest way to create a new tag.
678 .. _howto-custom-template-tags-inclusion-tags:
680 Inclusion tags
681 ~~~~~~~~~~~~~~
683 Another common type of template tag is the type that displays some data by
684 rendering *another* template. For example, Django's admin interface uses custom
685 template tags to display the buttons along the bottom of the "add/change" form
686 pages. Those buttons always look the same, but the link targets change depending
687 on the object being edited -- so they're a perfect case for using a small
688 template that is filled with details from the current object. (In the admin's
689 case, this is the ``submit_row`` tag.)
691 These sorts of tags are called "inclusion tags".
693 Writing inclusion tags is probably best demonstrated by example. Let's write a
694 tag that outputs a list of choices for a given ``Poll`` object, such as was
695 created in the :ref:`tutorials <creating-models>`. We'll use the tag like this:
697 .. code-block:: html+django
699     {% show_results poll %}
701 ...and the output will be something like this:
703 .. code-block:: html
705     <ul>
706       <li>First choice</li>
707       <li>Second choice</li>
708       <li>Third choice</li>
709     </ul>
711 First, define the function that takes the argument and produces a dictionary of
712 data for the result. The important point here is we only need to return a
713 dictionary, not anything more complex. This will be used as a template context
714 for the template fragment. Example::
716     def show_results(poll):
717         choices = poll.choice_set.all()
718         return {'choices': choices}
720 Next, create the template used to render the tag's output. This template is a
721 fixed feature of the tag: the tag writer specifies it, not the template
722 designer. Following our example, the template is very simple:
724 .. code-block:: html+django
726     <ul>
727     {% for choice in choices %}
728         <li> {{ choice }} </li>
729     {% endfor %}
730     </ul>
732 Now, create and register the inclusion tag by calling the ``inclusion_tag()``
733 method on a ``Library`` object. Following our example, if the above template is
734 in a file called ``results.html`` in a directory that's searched by the template
735 loader, we'd register the tag like this::
737     # Here, register is a django.template.Library instance, as before
738     register.inclusion_tag('results.html')(show_results)
740 As always, decorator syntax works as well, so we could have written::
742     @register.inclusion_tag('results.html')
743     def show_results(poll):
744         ...
746 ...when first creating the function.
748 Sometimes, your inclusion tags might require a large number of arguments,
749 making it a pain for template authors to pass in all the arguments and remember
750 their order. To solve this, Django provides a ``takes_context`` option for
751 inclusion tags. If you specify ``takes_context`` in creating a template tag,
752 the tag will have no required arguments, and the underlying Python function
753 will have one argument -- the template context as of when the tag was called.
755 For example, say you're writing an inclusion tag that will always be used in a
756 context that contains ``home_link`` and ``home_title`` variables that point
757 back to the main page. Here's what the Python function would look like::
759     # The first argument *must* be called "context" here.
760     def jump_link(context):
761         return {
762             'link': context['home_link'],
763             'title': context['home_title'],
764         }
765     # Register the custom tag as an inclusion tag with takes_context=True.
766     register.inclusion_tag('link.html', takes_context=True)(jump_link)
768 (Note that the first parameter to the function *must* be called ``context``.)
770 In that ``register.inclusion_tag()`` line, we specified ``takes_context=True``
771 and the name of the template. Here's what the template ``link.html`` might look
772 like:
774 .. code-block:: html+django
776     Jump directly to <a href="{{ link }}">{{ title }}</a>.
778 Then, any time you want to use that custom tag, load its library and call it
779 without any arguments, like so:
781 .. code-block:: html+django
783     {% jump_link %}
785 Note that when you're using ``takes_context=True``, there's no need to pass
786 arguments to the template tag. It automatically gets access to the context.
788 The ``takes_context`` parameter defaults to ``False``. When it's set to *True*,
789 the tag is passed the context object, as in this example. That's the only
790 difference between this case and the previous ``inclusion_tag`` example.
792 Setting a variable in the context
793 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
795 The above example simply output a value. Generally, it's more flexible if your
796 template tags set template variables instead of outputting values. That way,
797 template authors can reuse the values that your template tags create.
799 To set a variable in the context, just use dictionary assignment on the context
800 object in the ``render()`` method. Here's an updated version of
801 ``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
802 outputting it::
804     class CurrentTimeNode2(template.Node):
805         def __init__(self, format_string):
806             self.format_string = format_string
807         def render(self, context):
808             context['current_time'] = datetime.datetime.now().strftime(self.format_string)
809             return ''
811 Note that ``render()`` returns the empty string. ``render()`` should always
812 return string output. If all the template tag does is set a variable,
813 ``render()`` should return the empty string.
815 Here's how you'd use this new version of the tag:
817 .. code-block:: html+django
819     {% current_time "%Y-%M-%d %I:%M %p" %}<p>The time is {{ current_time }}.</p>
821 But, there's a problem with ``CurrentTimeNode2``: The variable name
822 ``current_time`` is hard-coded. This means you'll need to make sure your
823 template doesn't use ``{{ current_time }}`` anywhere else, because the
824 ``{% current_time %}`` will blindly overwrite that variable's value. A cleaner
825 solution is to make the template tag specify the name of the output variable,
826 like so:
828 .. code-block:: html+django
830     {% current_time "%Y-%M-%d %I:%M %p" as my_current_time %}
831     <p>The current time is {{ my_current_time }}.</p>
833 To do that, you'll need to refactor both the compilation function and ``Node``
834 class, like so::
836     class CurrentTimeNode3(template.Node):
837         def __init__(self, format_string, var_name):
838             self.format_string = format_string
839             self.var_name = var_name
840         def render(self, context):
841             context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
842             return ''
844     import re
845     def do_current_time(parser, token):
846         # This version uses a regular expression to parse tag contents.
847         try:
848             # Splitting by None == splitting by spaces.
849             tag_name, arg = token.contents.split(None, 1)
850         except ValueError:
851             raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
852         m = re.search(r'(.*?) as (\w+)', arg)
853         if not m:
854             raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
855         format_string, var_name = m.groups()
856         if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
857             raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
858         return CurrentTimeNode3(format_string[1:-1], var_name)
860 The difference here is that ``do_current_time()`` grabs the format string and
861 the variable name, passing both to ``CurrentTimeNode3``.
863 Parsing until another block tag
864 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
866 Template tags can work in tandem. For instance, the standard ``{% comment %}``
867 tag hides everything until ``{% endcomment %}``. To create a template tag such
868 as this, use ``parser.parse()`` in your compilation function.
870 Here's how the standard ``{% comment %}`` tag is implemented::
872     def do_comment(parser, token):
873         nodelist = parser.parse(('endcomment',))
874         parser.delete_first_token()
875         return CommentNode()
877     class CommentNode(template.Node):
878         def render(self, context):
879             return ''
881 ``parser.parse()`` takes a tuple of names of block tags ''to parse until''. It
882 returns an instance of ``django.template.NodeList``, which is a list of
883 all ``Node`` objects that the parser encountered ''before'' it encountered
884 any of the tags named in the tuple.
886 In ``"nodelist = parser.parse(('endcomment',))"`` in the above example,
887 ``nodelist`` is a list of all nodes between the ``{% comment %}`` and
888 ``{% endcomment %}``, not counting ``{% comment %}`` and ``{% endcomment %}``
889 themselves.
891 After ``parser.parse()`` is called, the parser hasn't yet "consumed" the
892 ``{% endcomment %}`` tag, so the code needs to explicitly call
893 ``parser.delete_first_token()``.
895 ``CommentNode.render()`` simply returns an empty string. Anything between
896 ``{% comment %}`` and ``{% endcomment %}`` is ignored.
898 Parsing until another block tag, and saving contents
899 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
901 In the previous example, ``do_comment()`` discarded everything between
902 ``{% comment %}`` and ``{% endcomment %}``. Instead of doing that, it's
903 possible to do something with the code between block tags.
905 For example, here's a custom template tag, ``{% upper %}``, that capitalizes
906 everything between itself and ``{% endupper %}``.
908 Usage:
910 .. code-block:: html+django
912     {% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
914 As in the previous example, we'll use ``parser.parse()``. But this time, we
915 pass the resulting ``nodelist`` to the ``Node``::
917     def do_upper(parser, token):
918         nodelist = parser.parse(('endupper',))
919         parser.delete_first_token()
920         return UpperNode(nodelist)
922     class UpperNode(template.Node):
923         def __init__(self, nodelist):
924             self.nodelist = nodelist
925         def render(self, context):
926             output = self.nodelist.render(context)
927             return output.upper()
929 The only new concept here is the ``self.nodelist.render(context)`` in
930 ``UpperNode.render()``.
932 For more examples of complex rendering, see the source code for ``{% if %}``,
933 ``{% for %}``, ``{% ifequal %}`` and ``{% ifchanged %}``. They live in
934 ``django/template/defaulttags.py``.