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