1 .. _howto-custom-template-tags:
3 ================================
4 Custom template tags and filters
5 ================================
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.
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
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::
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
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
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::
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"
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
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()``
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')
147 return value.replace(arg, '')
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
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::
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``::
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
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 ``&`` into ``&``, 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
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
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
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:]
281 esc = conditional_escape
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
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
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.
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``
352 from django import template
353 def do_current_time(parser, token):
355 # split_contents() knows not to split quoted strings.
356 tag_name, format_string = token.split_contents()
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])
365 * ``parser`` is the template parser object. We don't need it in this
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
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
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.
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
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)
415 * ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
416 Always pass any options/parameters/arguments to a ``Node`` via its
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
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):
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
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' %}>
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
500 1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
502 2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
504 3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
506 4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
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
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.
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):
567 def shout(parser, token):
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):
602 # split_contents() knows not to split quoted strings.
603 tag_name, date_to_be_formatted, format_string = token.split_contents()
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,
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):
629 actual_date = self.date_to_be_formatted.resolve(context)
630 return actual_date.strftime(self.format_string)
631 except template.VariableDoesNotExist:
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::
662 def current_time(format_string):
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:
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:
706 <li>First choice</li>
707 <li>Second choice</li>
708 <li>Third choice</li>
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
727 {% for choice in choices %}
728 <li> {{ choice }} </li>
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):
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):
762 'link': context['home_link'],
763 'title': context['home_title'],
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
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
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
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)
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,
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``
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)
845 def do_current_time(parser, token):
846 # This version uses a regular expression to parse tag contents.
848 # Splitting by None == splitting by spaces.
849 tag_name, arg = token.contents.split(None, 1)
851 raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
852 m = re.search(r'(.*?) as (\w+)', arg)
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()
877 class CommentNode(template.Node):
878 def render(self, context):
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 %}``
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 %}``.
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``.