Code

Changes between Initial Version and Version 1 of ClassDecoratorTags


Ignore:
Timestamp:
01/27/10 17:27:56 (4 years ago)
Author:
gsakkis
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}}}