Login

Enhancing template tags with "as variable" syntax

Author:
ctrochalakis
Posted:
August 26, 2009
Language:
Python
Version:
1.1
Score:
4 (after 4 ratings)

Add the decorator to an already defined templatetag that returns a Node object:

@with_as
def do_current_time(parser, token):
    ...
    return a_node

The decorator will patch the node's render method when the "as" syntax is specified and will update the context with the new variable. The following syntaxes are available:

{% current_time %}

{% current_time as time %}
{{ time }}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from functools import wraps

def with_as(f):
    """
    Decorator enabling a simple template tag to support "as my_var"
    syntax. When an as varible specified the result is added to the
    context under the variable name.

    example:
        @with_as
        def do_current_time(parser, token):
            ...
            return a_node

        {% current_time %}

        {% current_time as time %}
        {{ time }}
    """
    @wraps(f)
    def new_f(parser, token):
        contents = token.split_contents()

        if len(contents) < 3 or contents[-2] != 'as':
            return f(parser, token)

        as_var = contents[-1]
        # Remove 'as var_name' part from token
        token.contents =  ' '.join(contents[:-2])
        node = f(parser, token)
        patch_node(node, as_var)
        return node
    return new_f

def patch_node(node, as_var):
    """
    Patch the render method of node to silently update the context.
    """
    node._old_render = node.render

    # We patch a bound method, so self is not required
    @wraps(node._old_render)
    def new_render(context):
        context[as_var] = node._old_render(context)
        return ''
    
    node.render = new_render

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 8 months ago

Comments

Please login first before commenting.