1. ==============================================
    
  2. How to create custom template tags and filters
    
  3. ==============================================
    
  4. 
    
  5. Django's template language comes with a wide variety of :doc:`built-in
    
  6. tags and filters </ref/templates/builtins>` designed to address the
    
  7. presentation logic needs of your application. Nevertheless, you may
    
  8. find yourself needing functionality that is not covered by the core
    
  9. set of template primitives. You can extend the template engine by
    
  10. defining custom tags and filters using Python, and then make them
    
  11. available to your templates using the :ttag:`{% load %}<load>` tag.
    
  12. 
    
  13. Code layout
    
  14. ===========
    
  15. 
    
  16. The most common place to specify custom template tags and filters is inside
    
  17. a Django app. If they relate to an existing app, it makes sense to bundle them
    
  18. there; otherwise, they can be added to a new app. When a Django app is added
    
  19. to :setting:`INSTALLED_APPS`, any tags it defines in the conventional location
    
  20. described below are automatically made available to load within templates.
    
  21. 
    
  22. The app should contain a ``templatetags`` directory, at the same level as
    
  23. ``models.py``, ``views.py``, etc. If this doesn't already exist, create it -
    
  24. don't forget the ``__init__.py`` file to ensure the directory is treated as a
    
  25. Python package.
    
  26. 
    
  27. .. admonition:: Development server won't automatically restart
    
  28. 
    
  29.     After adding the ``templatetags``  module, you will need to restart your
    
  30.     server before you can use the tags or filters in templates.
    
  31. 
    
  32. Your custom tags and filters will live in a module inside the ``templatetags``
    
  33. directory. The name of the module file is the name you'll use to load the tags
    
  34. later, so be careful to pick a name that won't clash with custom tags and
    
  35. filters in another app.
    
  36. 
    
  37. For example, if your custom tags/filters are in a file called
    
  38. ``poll_extras.py``, your app layout might look like this::
    
  39. 
    
  40.     polls/
    
  41.         __init__.py
    
  42.         models.py
    
  43.         templatetags/
    
  44.             __init__.py
    
  45.             poll_extras.py
    
  46.         views.py
    
  47. 
    
  48. And in your template you would use the following:
    
  49. 
    
  50. .. code-block:: html+django
    
  51. 
    
  52.     {% load poll_extras %}
    
  53. 
    
  54. The app that contains the custom tags must be in :setting:`INSTALLED_APPS` in
    
  55. order for the :ttag:`{% load %}<load>` tag to work. This is a security feature:
    
  56. It allows you to host Python code for many template libraries on a single host
    
  57. machine without enabling access to all of them for every Django installation.
    
  58. 
    
  59. There's no limit on how many modules you put in the ``templatetags`` package.
    
  60. Just keep in mind that a :ttag:`{% load %}<load>` statement will load
    
  61. tags/filters for the given Python module name, not the name of the app.
    
  62. 
    
  63. To be a valid tag library, the module must contain a module-level variable
    
  64. named ``register`` that is a ``template.Library`` instance, in which all the
    
  65. tags and filters are registered. So, near the top of your module, put the
    
  66. following::
    
  67. 
    
  68.     from django import template
    
  69. 
    
  70.     register = template.Library()
    
  71. 
    
  72. Alternatively, template tag modules can be registered through the
    
  73. ``'libraries'`` argument to
    
  74. :class:`~django.template.backends.django.DjangoTemplates`. This is useful if
    
  75. you want to use a different label from the template tag module name when
    
  76. loading template tags. It also enables you to register tags without installing
    
  77. an application.
    
  78. 
    
  79. .. admonition:: Behind the scenes
    
  80. 
    
  81.     For a ton of examples, read the source code for Django's default filters
    
  82.     and tags. They're in :source:`django/template/defaultfilters.py` and
    
  83.     :source:`django/template/defaulttags.py`, respectively.
    
  84. 
    
  85.     For more information on the :ttag:`load` tag, read its documentation.
    
  86. 
    
  87. .. _howto-writing-custom-template-filters:
    
  88. 
    
  89. Writing custom template filters
    
  90. ===============================
    
  91. 
    
  92. Custom filters are Python functions that take one or two arguments:
    
  93. 
    
  94. * The value of the variable (input) -- not necessarily a string.
    
  95. * The value of the argument -- this can have a default value, or be left
    
  96.   out altogether.
    
  97. 
    
  98. For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
    
  99. passed the variable ``var`` and the argument ``"bar"``.
    
  100. 
    
  101. Since the template language doesn't provide exception handling, any exception
    
  102. raised from a template filter will be exposed as a server error. Thus, filter
    
  103. functions should avoid raising exceptions if there is a reasonable fallback
    
  104. value to return. In case of input that represents a clear bug in a template,
    
  105. raising an exception may still be better than silent failure which hides the
    
  106. bug.
    
  107. 
    
  108. Here's an example filter definition::
    
  109. 
    
  110.     def cut(value, arg):
    
  111.         """Removes all values of arg from the given string"""
    
  112.         return value.replace(arg, '')
    
  113. 
    
  114. And here's an example of how that filter would be used:
    
  115. 
    
  116. .. code-block:: html+django
    
  117. 
    
  118.     {{ somevariable|cut:"0" }}
    
  119. 
    
  120. Most filters don't take arguments. In this case, leave the argument out of your
    
  121. function::
    
  122. 
    
  123.     def lower(value): # Only one argument.
    
  124.         """Converts a string into all lowercase"""
    
  125.         return value.lower()
    
  126. 
    
  127. Registering custom filters
    
  128. --------------------------
    
  129. 
    
  130. .. method:: django.template.Library.filter()
    
  131. 
    
  132. Once you've written your filter definition, you need to register it with
    
  133. your ``Library`` instance, to make it available to Django's template language::
    
  134. 
    
  135.     register.filter('cut', cut)
    
  136.     register.filter('lower', lower)
    
  137. 
    
  138. The ``Library.filter()`` method takes two arguments:
    
  139. 
    
  140. 1. The name of the filter -- a string.
    
  141. 2. The compilation function -- a Python function (not the name of the
    
  142.    function as a string).
    
  143. 
    
  144. You can use ``register.filter()`` as a decorator instead::
    
  145. 
    
  146.     @register.filter(name='cut')
    
  147.     def cut(value, arg):
    
  148.         return value.replace(arg, '')
    
  149. 
    
  150.     @register.filter
    
  151.     def lower(value):
    
  152.         return value.lower()
    
  153. 
    
  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.
    
  156. 
    
  157. Finally, ``register.filter()`` also accepts three keyword arguments,
    
  158. ``is_safe``, ``needs_autoescape``, and ``expects_localtime``. These arguments
    
  159. are described in :ref:`filters and auto-escaping <filters-auto-escaping>` and
    
  160. :ref:`filters and time zones <filters-timezones>` below.
    
  161. 
    
  162. Template filters that expect strings
    
  163. ------------------------------------
    
  164. 
    
  165. .. method:: django.template.defaultfilters.stringfilter()
    
  166. 
    
  167. If you're writing a template filter that only expects a string as the first
    
  168. argument, you should use the decorator ``stringfilter``. This will
    
  169. convert an object to its string value before being passed to your function::
    
  170. 
    
  171.     from django import template
    
  172.     from django.template.defaultfilters import stringfilter
    
  173. 
    
  174.     register = template.Library()
    
  175. 
    
  176.     @register.filter
    
  177.     @stringfilter
    
  178.     def lower(value):
    
  179.         return value.lower()
    
  180. 
    
  181. This way, you'll be able to pass, say, an integer to this filter, and it
    
  182. won't cause an ``AttributeError`` (because integers don't have ``lower()``
    
  183. methods).
    
  184. 
    
  185. .. _filters-auto-escaping:
    
  186. 
    
  187. Filters and auto-escaping
    
  188. -------------------------
    
  189. 
    
  190. When writing a custom filter, give some thought to how the filter will interact
    
  191. with Django's auto-escaping behavior. Note that two types of strings can be
    
  192. passed around inside the template code:
    
  193. 
    
  194. * **Raw strings** are the native Python strings. On output, they're escaped if
    
  195.   auto-escaping is in effect and presented unchanged, otherwise.
    
  196. 
    
  197. * **Safe strings** are strings that have been marked safe from further
    
  198.   escaping at output time. Any necessary escaping has already been done.
    
  199.   They're commonly used for output that contains raw HTML that is intended
    
  200.   to be interpreted as-is on the client side.
    
  201. 
    
  202.   Internally, these strings are of type
    
  203.   :class:`~django.utils.safestring.SafeString`. You can test for them
    
  204.   using code like::
    
  205. 
    
  206.       from django.utils.safestring import SafeString
    
  207. 
    
  208.       if isinstance(value, SafeString):
    
  209.           # Do something with the "safe" string.
    
  210.           ...
    
  211. 
    
  212. Template filter code falls into one of two situations:
    
  213. 
    
  214. 1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
    
  215.    ``'``, ``"`` or ``&``) into the result that were not already present. In
    
  216.    this case, you can let Django take care of all the auto-escaping
    
  217.    handling for you. All you need to do is set the ``is_safe`` flag to ``True``
    
  218.    when you register your filter function, like so::
    
  219. 
    
  220.        @register.filter(is_safe=True)
    
  221.        def myfilter(value):
    
  222.            return value
    
  223. 
    
  224.    This flag tells Django that if a "safe" string is passed into your
    
  225.    filter, the result will still be "safe" and if a non-safe string is
    
  226.    passed in, Django will automatically escape it, if necessary.
    
  227. 
    
  228.    You can think of this as meaning "this filter is safe -- it doesn't
    
  229.    introduce any possibility of unsafe HTML."
    
  230. 
    
  231.    The reason ``is_safe`` is necessary is because there are plenty of
    
  232.    normal string operations that will turn a ``SafeData`` object back into
    
  233.    a normal ``str`` object and, rather than try to catch them all, which would
    
  234.    be very difficult, Django repairs the damage after the filter has completed.
    
  235. 
    
  236.    For example, suppose you have a filter that adds the string ``xx`` to
    
  237.    the end of any input. Since this introduces no dangerous HTML characters
    
  238.    to the result (aside from any that were already present), you should
    
  239.    mark your filter with ``is_safe``::
    
  240. 
    
  241.        @register.filter(is_safe=True)
    
  242.        def add_xx(value):
    
  243.            return '%sxx' % value
    
  244. 
    
  245.    When this filter is used in a template where auto-escaping is enabled,
    
  246.    Django will escape the output whenever the input is not already marked
    
  247.    as "safe".
    
  248. 
    
  249.    By default, ``is_safe`` is ``False``, and you can omit it from any filters
    
  250.    where it isn't required.
    
  251. 
    
  252.    Be careful when deciding if your filter really does leave safe strings
    
  253.    as safe. If you're *removing* characters, you might inadvertently leave
    
  254.    unbalanced HTML tags or entities in the result. For example, removing a
    
  255.    ``>`` from the input might turn ``<a>`` into ``<a``, which would need to
    
  256.    be escaped on output to avoid causing problems. Similarly, removing a
    
  257.    semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
    
  258.    valid entity and thus needs further escaping. Most cases won't be nearly
    
  259.    this tricky, but keep an eye out for any problems like that when
    
  260.    reviewing your code.
    
  261. 
    
  262.    Marking a filter ``is_safe`` will coerce the filter's return value to
    
  263.    a string.  If your filter should return a boolean or other non-string
    
  264.    value, marking it ``is_safe`` will probably have unintended
    
  265.    consequences (such as converting a boolean False to the string
    
  266.    'False').
    
  267. 
    
  268. 2. Alternatively, your filter code can manually take care of any necessary
    
  269.    escaping. This is necessary when you're introducing new HTML markup into
    
  270.    the result. You want to mark the output as safe from further
    
  271.    escaping so that your HTML markup isn't escaped further, so you'll need
    
  272.    to handle the input yourself.
    
  273. 
    
  274.    To mark the output as a safe string, use
    
  275.    :func:`django.utils.safestring.mark_safe`.
    
  276. 
    
  277.    Be careful, though. You need to do more than just mark the output as
    
  278.    safe. You need to ensure it really *is* safe, and what you do depends on
    
  279.    whether auto-escaping is in effect. The idea is to write filters that
    
  280.    can operate in templates where auto-escaping is either on or off in
    
  281.    order to make things easier for your template authors.
    
  282. 
    
  283.    In order for your filter to know the current auto-escaping state, set the
    
  284.    ``needs_autoescape`` flag to ``True`` when you register your filter function.
    
  285.    (If you don't specify this flag, it defaults to ``False``). This flag tells
    
  286.    Django that your filter function wants to be passed an extra keyword
    
  287.    argument, called ``autoescape``, that is ``True`` if auto-escaping is in
    
  288.    effect and ``False`` otherwise. It is recommended to set the default of the
    
  289.    ``autoescape`` parameter to ``True``, so that if you call the function
    
  290.    from Python code it will have escaping enabled by default.
    
  291. 
    
  292.    For example, let's write a filter that emphasizes the first character of
    
  293.    a string::
    
  294. 
    
  295.       from django import template
    
  296.       from django.utils.html import conditional_escape
    
  297.       from django.utils.safestring import mark_safe
    
  298. 
    
  299.       register = template.Library()
    
  300. 
    
  301.       @register.filter(needs_autoescape=True)
    
  302.       def initial_letter_filter(text, autoescape=True):
    
  303.           first, other = text[0], text[1:]
    
  304.           if autoescape:
    
  305.               esc = conditional_escape
    
  306.           else:
    
  307.               esc = lambda x: x
    
  308.           result = '<strong>%s</strong>%s' % (esc(first), esc(other))
    
  309.           return mark_safe(result)
    
  310. 
    
  311.    The ``needs_autoescape`` flag and the ``autoescape`` keyword argument mean
    
  312.    that our function will know whether automatic escaping is in effect when the
    
  313.    filter is called. We use ``autoescape`` to decide whether the input data
    
  314.    needs to be passed through ``django.utils.html.conditional_escape`` or not.
    
  315.    (In the latter case, we use the identity function as the "escape" function.)
    
  316.    The ``conditional_escape()`` function is like ``escape()`` except it only
    
  317.    escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
    
  318.    instance is passed to ``conditional_escape()``, the data is returned
    
  319.    unchanged.
    
  320. 
    
  321.    Finally, in the above example, we remember to mark the result as safe
    
  322.    so that our HTML is inserted directly into the template without further
    
  323.    escaping.
    
  324. 
    
  325.    There's no need to worry about the ``is_safe`` flag in this case
    
  326.    (although including it wouldn't hurt anything). Whenever you manually
    
  327.    handle the auto-escaping issues and return a safe string, the
    
  328.    ``is_safe`` flag won't change anything either way.
    
  329. 
    
  330. .. warning:: Avoiding XSS vulnerabilities when reusing built-in filters
    
  331. 
    
  332.     Django's built-in filters have ``autoescape=True`` by default in order to
    
  333.     get the proper autoescaping behavior and avoid a cross-site script
    
  334.     vulnerability.
    
  335. 
    
  336.     In older versions of Django, be careful when reusing Django's built-in
    
  337.     filters as ``autoescape`` defaults to ``None``. You'll need to pass
    
  338.     ``autoescape=True`` to get autoescaping.
    
  339. 
    
  340.     For example, if you wanted to write a custom filter called
    
  341.     ``urlize_and_linebreaks`` that combined the :tfilter:`urlize` and
    
  342.     :tfilter:`linebreaksbr` filters, the filter would look like::
    
  343. 
    
  344.         from django.template.defaultfilters import linebreaksbr, urlize
    
  345. 
    
  346.         @register.filter(needs_autoescape=True)
    
  347.         def urlize_and_linebreaks(text, autoescape=True):
    
  348.             return linebreaksbr(
    
  349.                 urlize(text, autoescape=autoescape),
    
  350.                 autoescape=autoescape
    
  351.             )
    
  352. 
    
  353.     Then:
    
  354. 
    
  355.     .. code-block:: html+django
    
  356. 
    
  357.         {{ comment|urlize_and_linebreaks }}
    
  358. 
    
  359.     would be equivalent to:
    
  360. 
    
  361.     .. code-block:: html+django
    
  362. 
    
  363.         {{ comment|urlize|linebreaksbr }}
    
  364. 
    
  365. .. _filters-timezones:
    
  366. 
    
  367. Filters and time zones
    
  368. ----------------------
    
  369. 
    
  370. If you write a custom filter that operates on :class:`~datetime.datetime`
    
  371. objects, you'll usually register it with the ``expects_localtime`` flag set to
    
  372. ``True``::
    
  373. 
    
  374.     @register.filter(expects_localtime=True)
    
  375.     def businesshours(value):
    
  376.         try:
    
  377.             return 9 <= value.hour < 17
    
  378.         except AttributeError:
    
  379.             return ''
    
  380. 
    
  381. When this flag is set, if the first argument to your filter is a time zone
    
  382. aware datetime, Django will convert it to the current time zone before passing
    
  383. it to your filter when appropriate, according to :ref:`rules for time zones
    
  384. conversions in templates <time-zones-in-templates>`.
    
  385. 
    
  386. .. _howto-writing-custom-template-tags:
    
  387. 
    
  388. Writing custom template tags
    
  389. ============================
    
  390. 
    
  391. Tags are more complex than filters, because tags can do anything. Django
    
  392. provides a number of shortcuts that make writing most types of tags easier.
    
  393. First we'll explore those shortcuts, then explain how to write a tag from
    
  394. scratch for those cases when the shortcuts aren't powerful enough.
    
  395. 
    
  396. .. _howto-custom-template-tags-simple-tags:
    
  397. 
    
  398. Simple tags
    
  399. -----------
    
  400. 
    
  401. .. method:: django.template.Library.simple_tag()
    
  402. 
    
  403. Many template tags take a number of arguments -- strings or template variables
    
  404. -- and return a result after doing some processing based solely on
    
  405. the input arguments and some external information. For example, a
    
  406. ``current_time`` tag might accept a format string and return the time as a
    
  407. string formatted accordingly.
    
  408. 
    
  409. To ease the creation of these types of tags, Django provides a helper function,
    
  410. ``simple_tag``. This function, which is a method of
    
  411. ``django.template.Library``, takes a function that accepts any number of
    
  412. arguments, wraps it in a ``render`` function and the other necessary bits
    
  413. mentioned above and registers it with the template system.
    
  414. 
    
  415. Our ``current_time`` function could thus be written like this::
    
  416. 
    
  417.     import datetime
    
  418.     from django import template
    
  419. 
    
  420.     register = template.Library()
    
  421. 
    
  422.     @register.simple_tag
    
  423.     def current_time(format_string):
    
  424.         return datetime.datetime.now().strftime(format_string)
    
  425. 
    
  426. A few things to note about the ``simple_tag`` helper function:
    
  427. 
    
  428. * Checking for the required number of arguments, etc., has already been
    
  429.   done by the time our function is called, so we don't need to do that.
    
  430. * The quotes around the argument (if any) have already been stripped away,
    
  431.   so we receive a plain string.
    
  432. * If the argument was a template variable, our function is passed the
    
  433.   current value of the variable, not the variable itself.
    
  434. 
    
  435. Unlike other tag utilities, ``simple_tag`` passes its output through
    
  436. :func:`~django.utils.html.conditional_escape` if the template context is in
    
  437. autoescape mode, to ensure correct HTML and protect you from XSS
    
  438. vulnerabilities.
    
  439. 
    
  440. If additional escaping is not desired, you will need to use
    
  441. :func:`~django.utils.safestring.mark_safe` if you are absolutely sure that your
    
  442. code does not contain XSS vulnerabilities. For building small HTML snippets,
    
  443. use of :func:`~django.utils.html.format_html` instead of ``mark_safe()`` is
    
  444. strongly recommended.
    
  445. 
    
  446. If your template tag needs to access the current context, you can use the
    
  447. ``takes_context`` argument when registering your tag::
    
  448. 
    
  449.     @register.simple_tag(takes_context=True)
    
  450.     def current_time(context, format_string):
    
  451.         timezone = context['timezone']
    
  452.         return your_get_current_time_method(timezone, format_string)
    
  453. 
    
  454. Note that the first argument *must* be called ``context``.
    
  455. 
    
  456. For more information on how the ``takes_context`` option works, see the section
    
  457. on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.
    
  458. 
    
  459. If you need to rename your tag, you can provide a custom name for it::
    
  460. 
    
  461.     register.simple_tag(lambda x: x - 1, name='minusone')
    
  462. 
    
  463.     @register.simple_tag(name='minustwo')
    
  464.     def some_function(value):
    
  465.         return value - 2
    
  466. 
    
  467. ``simple_tag`` functions may accept any number of positional or keyword
    
  468. arguments. For example::
    
  469. 
    
  470.     @register.simple_tag
    
  471.     def my_tag(a, b, *args, **kwargs):
    
  472.         warning = kwargs['warning']
    
  473.         profile = kwargs['profile']
    
  474.         ...
    
  475.         return ...
    
  476. 
    
  477. Then in the template any number of arguments, separated by spaces, may be
    
  478. passed to the template tag. Like in Python, the values for keyword arguments
    
  479. are set using the equal sign ("``=``") and must be provided after the
    
  480. positional arguments. For example:
    
  481. 
    
  482. .. code-block:: html+django
    
  483. 
    
  484.     {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
    
  485. 
    
  486. It's possible to store the tag results in a template variable rather than
    
  487. directly outputting it. This is done by using the ``as`` argument followed by
    
  488. the variable name. Doing so enables you to output the content yourself where
    
  489. you see fit:
    
  490. 
    
  491. .. code-block:: html+django
    
  492. 
    
  493.     {% current_time "%Y-%m-%d %I:%M %p" as the_time %}
    
  494.     <p>The time is {{ the_time }}.</p>
    
  495. 
    
  496. .. _howto-custom-template-tags-inclusion-tags:
    
  497. 
    
  498. Inclusion tags
    
  499. --------------
    
  500. 
    
  501. .. method:: django.template.Library.inclusion_tag()
    
  502. 
    
  503. Another common type of template tag is the type that displays some data by
    
  504. rendering *another* template. For example, Django's admin interface uses custom
    
  505. template tags to display the buttons along the bottom of the "add/change" form
    
  506. pages. Those buttons always look the same, but the link targets change
    
  507. depending on the object being edited -- so they're a perfect case for using a
    
  508. small template that is filled with details from the current object. (In the
    
  509. admin's case, this is the ``submit_row`` tag.)
    
  510. 
    
  511. These sorts of tags are called "inclusion tags".
    
  512. 
    
  513. Writing inclusion tags is probably best demonstrated by example. Let's write a
    
  514. tag that outputs a list of choices for a given ``Poll`` object, such as was
    
  515. created in the :ref:`tutorials <creating-models>`. We'll use the tag like this:
    
  516. 
    
  517. .. code-block:: html+django
    
  518. 
    
  519.     {% show_results poll %}
    
  520. 
    
  521. ...and the output will be something like this:
    
  522. 
    
  523. .. code-block:: html
    
  524. 
    
  525.     <ul>
    
  526.       <li>First choice</li>
    
  527.       <li>Second choice</li>
    
  528.       <li>Third choice</li>
    
  529.     </ul>
    
  530. 
    
  531. First, define the function that takes the argument and produces a dictionary of
    
  532. data for the result. The important point here is we only need to return a
    
  533. dictionary, not anything more complex. This will be used as a template context
    
  534. for the template fragment. Example::
    
  535. 
    
  536.     def show_results(poll):
    
  537.         choices = poll.choice_set.all()
    
  538.         return {'choices': choices}
    
  539. 
    
  540. Next, create the template used to render the tag's output. This template is a
    
  541. fixed feature of the tag: the tag writer specifies it, not the template
    
  542. designer. Following our example, the template is very short:
    
  543. 
    
  544. .. code-block:: html+django
    
  545. 
    
  546.     <ul>
    
  547.     {% for choice in choices %}
    
  548.         <li> {{ choice }} </li>
    
  549.     {% endfor %}
    
  550.     </ul>
    
  551. 
    
  552. Now, create and register the inclusion tag by calling the ``inclusion_tag()``
    
  553. method on a ``Library`` object. Following our example, if the above template is
    
  554. in a file called ``results.html`` in a directory that's searched by the
    
  555. template loader, we'd register the tag like this::
    
  556. 
    
  557.     # Here, register is a django.template.Library instance, as before
    
  558.     @register.inclusion_tag('results.html')
    
  559.     def show_results(poll):
    
  560.         ...
    
  561. 
    
  562. Alternatively it is possible to register the inclusion tag using a
    
  563. :class:`django.template.Template` instance::
    
  564. 
    
  565.     from django.template.loader import get_template
    
  566.     t = get_template('results.html')
    
  567.     register.inclusion_tag(t)(show_results)
    
  568. 
    
  569. ...when first creating the function.
    
  570. 
    
  571. Sometimes, your inclusion tags might require a large number of arguments,
    
  572. making it a pain for template authors to pass in all the arguments and remember
    
  573. their order. To solve this, Django provides a ``takes_context`` option for
    
  574. inclusion tags. If you specify ``takes_context`` in creating a template tag,
    
  575. the tag will have no required arguments, and the underlying Python function
    
  576. will have one argument -- the template context as of when the tag was called.
    
  577. 
    
  578. For example, say you're writing an inclusion tag that will always be used in a
    
  579. context that contains ``home_link`` and ``home_title`` variables that point
    
  580. back to the main page. Here's what the Python function would look like::
    
  581. 
    
  582.     @register.inclusion_tag('link.html', takes_context=True)
    
  583.     def jump_link(context):
    
  584.         return {
    
  585.             'link': context['home_link'],
    
  586.             'title': context['home_title'],
    
  587.         }
    
  588. 
    
  589. Note that the first parameter to the function *must* be called ``context``.
    
  590. 
    
  591. In that ``register.inclusion_tag()`` line, we specified ``takes_context=True``
    
  592. and the name of the template. Here's what the template ``link.html`` might look
    
  593. like:
    
  594. 
    
  595. .. code-block:: html+django
    
  596. 
    
  597.     Jump directly to <a href="{{ link }}">{{ title }}</a>.
    
  598. 
    
  599. Then, any time you want to use that custom tag, load its library and call it
    
  600. without any arguments, like so:
    
  601. 
    
  602. .. code-block:: html+django
    
  603. 
    
  604.     {% jump_link %}
    
  605. 
    
  606. Note that when you're using ``takes_context=True``, there's no need to pass
    
  607. arguments to the template tag. It automatically gets access to the context.
    
  608. 
    
  609. The ``takes_context`` parameter defaults to ``False``. When it's set to
    
  610. ``True``, the tag is passed the context object, as in this example. That's the
    
  611. only difference between this case and the previous ``inclusion_tag`` example.
    
  612. 
    
  613. ``inclusion_tag`` functions may accept any number of positional or keyword
    
  614. arguments. For example::
    
  615. 
    
  616.     @register.inclusion_tag('my_template.html')
    
  617.     def my_tag(a, b, *args, **kwargs):
    
  618.         warning = kwargs['warning']
    
  619.         profile = kwargs['profile']
    
  620.         ...
    
  621.         return ...
    
  622. 
    
  623. Then in the template any number of arguments, separated by spaces, may be
    
  624. passed to the template tag. Like in Python, the values for keyword arguments
    
  625. are set using the equal sign ("``=``") and must be provided after the
    
  626. positional arguments. For example:
    
  627. 
    
  628. .. code-block:: html+django
    
  629. 
    
  630.     {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
    
  631. 
    
  632. Advanced custom template tags
    
  633. -----------------------------
    
  634. 
    
  635. Sometimes the basic features for custom template tag creation aren't enough.
    
  636. Don't worry, Django gives you complete access to the internals required to build
    
  637. a template tag from the ground up.
    
  638. 
    
  639. A quick overview
    
  640. ----------------
    
  641. 
    
  642. The template system works in a two-step process: compiling and rendering. To
    
  643. define a custom template tag, you specify how the compilation works and how
    
  644. the rendering works.
    
  645. 
    
  646. When Django compiles a template, it splits the raw template text into
    
  647. ''nodes''. Each node is an instance of ``django.template.Node`` and has
    
  648. a ``render()`` method. A compiled template is a list of ``Node`` objects. When
    
  649. you call ``render()`` on a compiled template object, the template calls
    
  650. ``render()`` on each ``Node`` in its node list, with the given context.  The
    
  651. results are all concatenated together to form the output of the template.
    
  652. 
    
  653. Thus, to define a custom template tag, you specify how the raw template tag is
    
  654. converted into a ``Node`` (the compilation function), and what the node's
    
  655. ``render()`` method does.
    
  656. 
    
  657. Writing the compilation function
    
  658. --------------------------------
    
  659. 
    
  660. For each template tag the template parser encounters, it calls a Python
    
  661. function with the tag contents and the parser object itself. This function is
    
  662. responsible for returning a ``Node`` instance based on the contents of the tag.
    
  663. 
    
  664. For example, let's write a full implementation of our template tag,
    
  665. ``{% current_time %}``, that displays the current date/time, formatted according
    
  666. to a parameter given in the tag, in :func:`~time.strftime` syntax. It's a good
    
  667. idea to decide the tag syntax before anything else. In our case, let's say the
    
  668. tag should be used like this:
    
  669. 
    
  670. .. code-block:: html+django
    
  671. 
    
  672.     <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
    
  673. 
    
  674. The parser for this function should grab the parameter and create a ``Node``
    
  675. object::
    
  676. 
    
  677.     from django import template
    
  678. 
    
  679.     def do_current_time(parser, token):
    
  680.         try:
    
  681.             # split_contents() knows not to split quoted strings.
    
  682.             tag_name, format_string = token.split_contents()
    
  683.         except ValueError:
    
  684.             raise template.TemplateSyntaxError(
    
  685.                 "%r tag requires a single argument" % token.contents.split()[0]
    
  686.             )
    
  687.         if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
    
  688.             raise template.TemplateSyntaxError(
    
  689.                 "%r tag's argument should be in quotes" % tag_name
    
  690.             )
    
  691.         return CurrentTimeNode(format_string[1:-1])
    
  692. 
    
  693. Notes:
    
  694. 
    
  695. * ``parser`` is the template parser object. We don't need it in this
    
  696.   example.
    
  697. 
    
  698. * ``token.contents`` is a string of the raw contents of the tag. In our
    
  699.   example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
    
  700. 
    
  701. * The ``token.split_contents()`` method separates the arguments on spaces
    
  702.   while keeping quoted strings together. The more straightforward
    
  703.   ``token.contents.split()`` wouldn't be as robust, as it would naively
    
  704.   split on *all* spaces, including those within quoted strings. It's a good
    
  705.   idea to always use ``token.split_contents()``.
    
  706. 
    
  707. * This function is responsible for raising
    
  708.   ``django.template.TemplateSyntaxError``, with helpful messages, for
    
  709.   any syntax error.
    
  710. 
    
  711. * The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
    
  712.   Don't hard-code the tag's name in your error messages, because that
    
  713.   couples the tag's name to your function. ``token.contents.split()[0]``
    
  714.   will ''always'' be the name of your tag -- even when the tag has no
    
  715.   arguments.
    
  716. 
    
  717. * The function returns a ``CurrentTimeNode`` with everything the node needs
    
  718.   to know about this tag. In this case, it passes the argument --
    
  719.   ``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
    
  720.   template tag are removed in ``format_string[1:-1]``.
    
  721. 
    
  722. * The parsing is very low-level. The Django developers have experimented
    
  723.   with writing small frameworks on top of this parsing system, using
    
  724.   techniques such as EBNF grammars, but those experiments made the template
    
  725.   engine too slow. It's low-level because that's fastest.
    
  726. 
    
  727. Writing the renderer
    
  728. --------------------
    
  729. 
    
  730. The second step in writing custom tags is to define a ``Node`` subclass that
    
  731. has a ``render()`` method.
    
  732. 
    
  733. Continuing the above example, we need to define ``CurrentTimeNode``::
    
  734. 
    
  735.     import datetime
    
  736.     from django import template
    
  737. 
    
  738.     class CurrentTimeNode(template.Node):
    
  739.         def __init__(self, format_string):
    
  740.             self.format_string = format_string
    
  741. 
    
  742.         def render(self, context):
    
  743.             return datetime.datetime.now().strftime(self.format_string)
    
  744. 
    
  745. Notes:
    
  746. 
    
  747. * ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
    
  748.   Always pass any options/parameters/arguments to a ``Node`` via its
    
  749.   ``__init__()``.
    
  750. 
    
  751. * The ``render()`` method is where the work actually happens.
    
  752. 
    
  753. * ``render()`` should generally fail silently, particularly in a production
    
  754.   environment. In some cases however, particularly if
    
  755.   ``context.template.engine.debug`` is ``True``, this method may raise an
    
  756.   exception to make debugging easier. For example, several core tags raise
    
  757.   ``django.template.TemplateSyntaxError`` if they receive the wrong number or
    
  758.   type of arguments.
    
  759. 
    
  760. Ultimately, this decoupling of compilation and rendering results in an
    
  761. efficient template system, because a template can render multiple contexts
    
  762. without having to be parsed multiple times.
    
  763. 
    
  764. .. _tags-auto-escaping:
    
  765. 
    
  766. Auto-escaping considerations
    
  767. ----------------------------
    
  768. 
    
  769. The output from template tags is **not** automatically run through the
    
  770. auto-escaping filters (with the exception of
    
  771. :meth:`~django.template.Library.simple_tag` as described above). However, there
    
  772. are still a couple of things you should keep in mind when writing a template
    
  773. tag.
    
  774. 
    
  775. If the ``render()`` method of your template tag stores the result in a context
    
  776. variable (rather than returning the result in a string), it should take care
    
  777. to call ``mark_safe()`` if appropriate. When the variable is ultimately
    
  778. rendered, it will be affected by the auto-escape setting in effect at the
    
  779. time, so content that should be safe from further escaping needs to be marked
    
  780. as such.
    
  781. 
    
  782. Also, if your template tag creates a new context for performing some
    
  783. sub-rendering, set the auto-escape attribute to the current context's value.
    
  784. The ``__init__`` method for the ``Context`` class takes a parameter called
    
  785. ``autoescape`` that you can use for this purpose. For example::
    
  786. 
    
  787.     from django.template import Context
    
  788. 
    
  789.     def render(self, context):
    
  790.         # ...
    
  791.         new_context = Context({'var': obj}, autoescape=context.autoescape)
    
  792.         # ... Do something with new_context ...
    
  793. 
    
  794. This is not a very common situation, but it's useful if you're rendering a
    
  795. template yourself. For example::
    
  796. 
    
  797.     def render(self, context):
    
  798.         t = context.template.engine.get_template('small_fragment.html')
    
  799.         return t.render(Context({'var': obj}, autoescape=context.autoescape))
    
  800. 
    
  801. If we had neglected to pass in the current ``context.autoescape`` value to our
    
  802. new ``Context`` in this example, the results would have *always* been
    
  803. automatically escaped, which may not be the desired behavior if the template
    
  804. tag is used inside a :ttag:`{% autoescape off %}<autoescape>` block.
    
  805. 
    
  806. .. _template_tag_thread_safety:
    
  807. 
    
  808. Thread-safety considerations
    
  809. ----------------------------
    
  810. 
    
  811. Once a node is parsed, its ``render`` method may be called any number of times.
    
  812. Since Django is sometimes run in multi-threaded environments, a single node may
    
  813. be simultaneously rendering with different contexts in response to two separate
    
  814. requests. Therefore, it's important to make sure your template tags are thread
    
  815. safe.
    
  816. 
    
  817. To make sure your template tags are thread safe, you should never store state
    
  818. information on the node itself. For example, Django provides a builtin
    
  819. :ttag:`cycle` template tag that cycles among a list of given strings each time
    
  820. it's rendered:
    
  821. 
    
  822. .. code-block:: html+django
    
  823. 
    
  824.     {% for o in some_list %}
    
  825.         <tr class="{% cycle 'row1' 'row2' %}">
    
  826.             ...
    
  827.         </tr>
    
  828.     {% endfor %}
    
  829. 
    
  830. A naive implementation of ``CycleNode`` might look something like this::
    
  831. 
    
  832.     import itertools
    
  833.     from django import template
    
  834. 
    
  835.     class CycleNode(template.Node):
    
  836.         def __init__(self, cyclevars):
    
  837.             self.cycle_iter = itertools.cycle(cyclevars)
    
  838. 
    
  839.         def render(self, context):
    
  840.             return next(self.cycle_iter)
    
  841. 
    
  842. But, suppose we have two templates rendering the template snippet from above at
    
  843. the same time:
    
  844. 
    
  845. #. Thread 1 performs its first loop iteration, ``CycleNode.render()``
    
  846.    returns 'row1'
    
  847. #. Thread 2 performs its first loop iteration, ``CycleNode.render()``
    
  848.    returns 'row2'
    
  849. #. Thread 1 performs its second loop iteration, ``CycleNode.render()``
    
  850.    returns 'row1'
    
  851. #. Thread 2 performs its second loop iteration, ``CycleNode.render()``
    
  852.    returns 'row2'
    
  853. 
    
  854. The CycleNode is iterating, but it's iterating globally. As far as Thread 1
    
  855. and Thread 2 are concerned, it's always returning the same value. This is
    
  856. not what we want!
    
  857. 
    
  858. To address this problem, Django provides a ``render_context`` that's associated
    
  859. with the ``context`` of the template that is currently being rendered. The
    
  860. ``render_context`` behaves like a Python dictionary, and should be used to
    
  861. store ``Node`` state between invocations of the ``render`` method.
    
  862. 
    
  863. Let's refactor our ``CycleNode`` implementation to use the ``render_context``::
    
  864. 
    
  865.     class CycleNode(template.Node):
    
  866.         def __init__(self, cyclevars):
    
  867.             self.cyclevars = cyclevars
    
  868. 
    
  869.         def render(self, context):
    
  870.             if self not in context.render_context:
    
  871.                 context.render_context[self] = itertools.cycle(self.cyclevars)
    
  872.             cycle_iter = context.render_context[self]
    
  873.             return next(cycle_iter)
    
  874. 
    
  875. Note that it's perfectly safe to store global information that will not change
    
  876. throughout the life of the ``Node`` as an attribute. In the case of
    
  877. ``CycleNode``, the ``cyclevars`` argument doesn't change after the ``Node`` is
    
  878. instantiated, so we don't need to put it in the ``render_context``. But state
    
  879. information that is specific to the template that is currently being rendered,
    
  880. like the current iteration of the ``CycleNode``, should be stored in the
    
  881. ``render_context``.
    
  882. 
    
  883. .. note::
    
  884.     Notice how we used ``self`` to scope the ``CycleNode`` specific information
    
  885.     within the ``render_context``. There may be multiple ``CycleNodes`` in a
    
  886.     given template, so we need to be careful not to clobber another node's
    
  887.     state information. The easiest way to do this is to always use ``self`` as
    
  888.     the key into ``render_context``. If you're keeping track of several state
    
  889.     variables, make ``render_context[self]`` a dictionary.
    
  890. 
    
  891. Registering the tag
    
  892. -------------------
    
  893. 
    
  894. Finally, register the tag with your module's ``Library`` instance, as explained
    
  895. in :ref:`writing custom template tags<howto-writing-custom-template-tags>`
    
  896. above. Example::
    
  897. 
    
  898.     register.tag('current_time', do_current_time)
    
  899. 
    
  900. The ``tag()`` method takes two arguments:
    
  901. 
    
  902. 1. The name of the template tag -- a string. If this is left out, the
    
  903.    name of the compilation function will be used.
    
  904. 2. The compilation function -- a Python function (not the name of the
    
  905.    function as a string).
    
  906. 
    
  907. As with filter registration, it is also possible to use this as a decorator::
    
  908. 
    
  909.     @register.tag(name="current_time")
    
  910.     def do_current_time(parser, token):
    
  911.         ...
    
  912. 
    
  913.     @register.tag
    
  914.     def shout(parser, token):
    
  915.         ...
    
  916. 
    
  917. If you leave off the ``name`` argument, as in the second example above, Django
    
  918. will use the function's name as the tag name.
    
  919. 
    
  920. Passing template variables to the tag
    
  921. -------------------------------------
    
  922. 
    
  923. Although you can pass any number of arguments to a template tag using
    
  924. ``token.split_contents()``, the arguments are all unpacked as
    
  925. string literals. A little more work is required in order to pass dynamic
    
  926. content (a template variable) to a template tag as an argument.
    
  927. 
    
  928. While the previous examples have formatted the current time into a string and
    
  929. returned the string, suppose you wanted to pass in a
    
  930. :class:`~django.db.models.DateTimeField` from an object and have the template
    
  931. tag format that date-time:
    
  932. 
    
  933. .. code-block:: html+django
    
  934. 
    
  935.     <p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p>
    
  936. 
    
  937. Initially, ``token.split_contents()`` will return three values:
    
  938. 
    
  939. 1. The tag name ``format_time``.
    
  940. 2. The string ``'blog_entry.date_updated'`` (without the surrounding
    
  941.    quotes).
    
  942. 3. The formatting string ``'"%Y-%m-%d %I:%M %p"'``. The return value from
    
  943.    ``split_contents()`` will include the leading and trailing quotes for
    
  944.    string literals like this.
    
  945. 
    
  946. Now your tag should begin to look like this::
    
  947. 
    
  948.     from django import template
    
  949. 
    
  950.     def do_format_time(parser, token):
    
  951.         try:
    
  952.             # split_contents() knows not to split quoted strings.
    
  953.             tag_name, date_to_be_formatted, format_string = token.split_contents()
    
  954.         except ValueError:
    
  955.             raise template.TemplateSyntaxError(
    
  956.                 "%r tag requires exactly two arguments" % token.contents.split()[0]
    
  957.             )
    
  958.         if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
    
  959.             raise template.TemplateSyntaxError(
    
  960.                 "%r tag's argument should be in quotes" % tag_name
    
  961.             )
    
  962.         return FormatTimeNode(date_to_be_formatted, format_string[1:-1])
    
  963. 
    
  964. You also have to change the renderer to retrieve the actual contents of the
    
  965. ``date_updated`` property of the ``blog_entry`` object.  This can be
    
  966. accomplished by using the ``Variable()`` class in ``django.template``.
    
  967. 
    
  968. To use the ``Variable`` class, instantiate it with the name of the variable to
    
  969. be resolved, and then call ``variable.resolve(context)``. So, for example::
    
  970. 
    
  971.     class FormatTimeNode(template.Node):
    
  972.         def __init__(self, date_to_be_formatted, format_string):
    
  973.             self.date_to_be_formatted = template.Variable(date_to_be_formatted)
    
  974.             self.format_string = format_string
    
  975. 
    
  976.         def render(self, context):
    
  977.             try:
    
  978.                 actual_date = self.date_to_be_formatted.resolve(context)
    
  979.                 return actual_date.strftime(self.format_string)
    
  980.             except template.VariableDoesNotExist:
    
  981.                 return ''
    
  982. 
    
  983. Variable resolution will throw a ``VariableDoesNotExist`` exception if it
    
  984. cannot resolve the string passed to it in the current context of the page.
    
  985. 
    
  986. Setting a variable in the context
    
  987. ---------------------------------
    
  988. 
    
  989. The above examples output a value. Generally, it's more flexible if your
    
  990. template tags set template variables instead of outputting values. That way,
    
  991. template authors can reuse the values that your template tags create.
    
  992. 
    
  993. To set a variable in the context, use dictionary assignment on the context
    
  994. object in the ``render()`` method. Here's an updated version of
    
  995. ``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
    
  996. outputting it::
    
  997. 
    
  998.     import datetime
    
  999.     from django import template
    
  1000. 
    
  1001.     class CurrentTimeNode2(template.Node):
    
  1002.         def __init__(self, format_string):
    
  1003.             self.format_string = format_string
    
  1004.         def render(self, context):
    
  1005.             context['current_time'] = datetime.datetime.now().strftime(self.format_string)
    
  1006.             return ''
    
  1007. 
    
  1008. Note that ``render()`` returns the empty string. ``render()`` should always
    
  1009. return string output. If all the template tag does is set a variable,
    
  1010. ``render()`` should return the empty string.
    
  1011. 
    
  1012. Here's how you'd use this new version of the tag:
    
  1013. 
    
  1014. .. code-block:: html+django
    
  1015. 
    
  1016.     {% current_time "%Y-%m-%d %I:%M %p" %}<p>The time is {{ current_time }}.</p>
    
  1017. 
    
  1018. .. admonition:: Variable scope in context
    
  1019. 
    
  1020.     Any variable set in the context will only be available in the same
    
  1021.     ``block`` of the template in which it was assigned. This behavior is
    
  1022.     intentional; it provides a scope for variables so that they don't conflict
    
  1023.     with context in other blocks.
    
  1024. 
    
  1025. But, there's a problem with ``CurrentTimeNode2``: The variable name
    
  1026. ``current_time`` is hard-coded. This means you'll need to make sure your
    
  1027. template doesn't use ``{{ current_time }}`` anywhere else, because the
    
  1028. ``{% current_time %}`` will blindly overwrite that variable's value. A cleaner
    
  1029. solution is to make the template tag specify the name of the output variable,
    
  1030. like so:
    
  1031. 
    
  1032. .. code-block:: html+django
    
  1033. 
    
  1034.     {% current_time "%Y-%m-%d %I:%M %p" as my_current_time %}
    
  1035.     <p>The current time is {{ my_current_time }}.</p>
    
  1036. 
    
  1037. To do that, you'll need to refactor both the compilation function and ``Node``
    
  1038. class, like so::
    
  1039. 
    
  1040.     import re
    
  1041. 
    
  1042.     class CurrentTimeNode3(template.Node):
    
  1043.         def __init__(self, format_string, var_name):
    
  1044.             self.format_string = format_string
    
  1045.             self.var_name = var_name
    
  1046.         def render(self, context):
    
  1047.             context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
    
  1048.             return ''
    
  1049. 
    
  1050.     def do_current_time(parser, token):
    
  1051.         # This version uses a regular expression to parse tag contents.
    
  1052.         try:
    
  1053.             # Splitting by None == splitting by spaces.
    
  1054.             tag_name, arg = token.contents.split(None, 1)
    
  1055.         except ValueError:
    
  1056.             raise template.TemplateSyntaxError(
    
  1057.                 "%r tag requires arguments" % token.contents.split()[0]
    
  1058.             )
    
  1059.         m = re.search(r'(.*?) as (\w+)', arg)
    
  1060.         if not m:
    
  1061.             raise template.TemplateSyntaxError("%r tag had invalid arguments" % tag_name)
    
  1062.         format_string, var_name = m.groups()
    
  1063.         if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
    
  1064.             raise template.TemplateSyntaxError(
    
  1065.                 "%r tag's argument should be in quotes" % tag_name
    
  1066.             )
    
  1067.         return CurrentTimeNode3(format_string[1:-1], var_name)
    
  1068. 
    
  1069. The difference here is that ``do_current_time()`` grabs the format string and
    
  1070. the variable name, passing both to ``CurrentTimeNode3``.
    
  1071. 
    
  1072. Finally, if you only need to have a simple syntax for your custom
    
  1073. context-updating template tag, consider using the
    
  1074. :meth:`~django.template.Library.simple_tag` shortcut, which supports assigning
    
  1075. the tag results to a template variable.
    
  1076. 
    
  1077. Parsing until another block tag
    
  1078. -------------------------------
    
  1079. 
    
  1080. Template tags can work in tandem. For instance, the standard
    
  1081. :ttag:`{% comment %}<comment>` tag hides everything until ``{% endcomment %}``.
    
  1082. To create a template tag such as this, use ``parser.parse()`` in your
    
  1083. compilation function.
    
  1084. 
    
  1085. Here's how a simplified ``{% comment %}`` tag might be implemented::
    
  1086. 
    
  1087.     def do_comment(parser, token):
    
  1088.         nodelist = parser.parse(('endcomment',))
    
  1089.         parser.delete_first_token()
    
  1090.         return CommentNode()
    
  1091. 
    
  1092.     class CommentNode(template.Node):
    
  1093.         def render(self, context):
    
  1094.             return ''
    
  1095. 
    
  1096. .. note::
    
  1097.     The actual implementation of :ttag:`{% comment %}<comment>` is slightly
    
  1098.     different in that it allows broken template tags to appear between
    
  1099.     ``{% comment %}`` and ``{% endcomment %}``. It does so by calling
    
  1100.     ``parser.skip_past('endcomment')`` instead of ``parser.parse(('endcomment',))``
    
  1101.     followed by ``parser.delete_first_token()``, thus avoiding the generation of a
    
  1102.     node list.
    
  1103. 
    
  1104. ``parser.parse()`` takes a tuple of names of block tags ''to parse until''. It
    
  1105. returns an instance of ``django.template.NodeList``, which is a list of
    
  1106. all ``Node`` objects that the parser encountered ''before'' it encountered
    
  1107. any of the tags named in the tuple.
    
  1108. 
    
  1109. In ``"nodelist = parser.parse(('endcomment',))"`` in the above example,
    
  1110. ``nodelist`` is a list of all nodes between the ``{% comment %}`` and
    
  1111. ``{% endcomment %}``, not counting ``{% comment %}`` and ``{% endcomment %}``
    
  1112. themselves.
    
  1113. 
    
  1114. After ``parser.parse()`` is called, the parser hasn't yet "consumed" the
    
  1115. ``{% endcomment %}`` tag, so the code needs to explicitly call
    
  1116. ``parser.delete_first_token()``.
    
  1117. 
    
  1118. ``CommentNode.render()`` returns an empty string. Anything between
    
  1119. ``{% comment %}`` and ``{% endcomment %}`` is ignored.
    
  1120. 
    
  1121. Parsing until another block tag, and saving contents
    
  1122. ----------------------------------------------------
    
  1123. 
    
  1124. In the previous example, ``do_comment()`` discarded everything between
    
  1125. ``{% comment %}`` and ``{% endcomment %}``. Instead of doing that, it's
    
  1126. possible to do something with the code between block tags.
    
  1127. 
    
  1128. For example, here's a custom template tag, ``{% upper %}``, that capitalizes
    
  1129. everything between itself and ``{% endupper %}``.
    
  1130. 
    
  1131. Usage:
    
  1132. 
    
  1133. .. code-block:: html+django
    
  1134. 
    
  1135.     {% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
    
  1136. 
    
  1137. As in the previous example, we'll use ``parser.parse()``. But this time, we
    
  1138. pass the resulting ``nodelist`` to the ``Node``::
    
  1139. 
    
  1140.     def do_upper(parser, token):
    
  1141.         nodelist = parser.parse(('endupper',))
    
  1142.         parser.delete_first_token()
    
  1143.         return UpperNode(nodelist)
    
  1144. 
    
  1145.     class UpperNode(template.Node):
    
  1146.         def __init__(self, nodelist):
    
  1147.             self.nodelist = nodelist
    
  1148.         def render(self, context):
    
  1149.             output = self.nodelist.render(context)
    
  1150.             return output.upper()
    
  1151. 
    
  1152. The only new concept here is the ``self.nodelist.render(context)`` in
    
  1153. ``UpperNode.render()``.
    
  1154. 
    
  1155. For more examples of complex rendering, see the source code of
    
  1156. :ttag:`{% for %}<for>` in ``django/template/defaulttags.py`` and
    
  1157. :ttag:`{% if %}<if>` in ``django/template/smartif.py``.