Changes between Initial Version and Version 1 of ClassDecoratorTags


Ignore:
Timestamp:
Jan 27, 2010, 7:27:56 PM (14 years ago)
Author:
George Sakkis
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ClassDecoratorTags

    v1 v1  
     1Defining a custom template tag consists of three parts: a compiling function, a rendering `Node` subclass and a tag registration with `register.tag()`. The latter can be used as a (function) decorator on the compiling function, simplifying things into two parts.
     2
     3A neat fact is that `register.tag()` can actually be used as a class decorator in Python 2.6+ to condense all steps into the `Node` subclass. The compiling function simply becomes the `__init__()` of the class. Here's the 'current_time' tag example from the docs:
     4
     5{{{
     6import datetime
     7from django import template
     8register = template.Library()
     9
     10@register.tag('current_time')
     11class CurrentTimeNode(template.Node):
     12    def __init__(self, parser, token):
     13        try:
     14            # split_contents() knows not to split quoted strings.
     15            tag_name, format_string = token.split_contents()
     16        except ValueError:
     17            raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
     18        if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
     19            raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
     20        self.format_string = str(format_string[1:-1])
     21       
     22    def render(self, context):
     23        return datetime.datetime.now().strftime(self.format_string)
     24}}}
     25
     26or even simpler, leave off the name argument and use the class name as the tag name:
     27
     28{{{
     29import datetime
     30from django import template
     31register = template.Library()
     32
     33@register.tag
     34class current_time(template.Node):
     35    def __init__(self, parser, token):
     36        try:
     37            # split_contents() knows not to split quoted strings.
     38            tag_name, format_string = token.split_contents()
     39        except ValueError:
     40            raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
     41        if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
     42            raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
     43        self.format_string = str(format_string[1:-1])
     44       
     45    def render(self, context):
     46        return datetime.datetime.now().strftime(self.format_string)
     47}}}
Back to Top