Enhancing template tags with "as variable" syntax

 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. Increment a variable in a Template by sachingupta006 2 years, 1 month ago
  2. Template Tag Render Decorator by stephen_mcd 4 years, 1 month ago
  3. django_template decorator by fredd4 6 years, 2 months ago
  4. Parse TemplateTag Variables Safely by evan_schulz 5 years, 9 months ago
  5. Private Context Decorator by acdha 4 years, 8 months ago

Comments

(Forgotten your password?)