Partial templates, combine with and include

 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from django.template import Library, Variable, Node
from django.template.loader import get_template
from django.template import TemplateSyntaxError

register = Library()

"""
Combines 'with' and 'include' to something useful:

For example: 
  {% partial "table_list.html" hot as urls and 1 as listid and "Hot items" as title %}

Will include the "table_list.html" file -- using the same include rules a django
and have the 'listid', 'urls', and 'title' variables set in the include context.
"""

class PartialNode(Node):
    def __init__(self, path, is_constant, params):
        self.params = params
        self.tmpl   = None
        self.vtmpl  = None

        if is_constant :
            try :
                self.tmpl = get_template(path)
            except : 
                if settings.TEMPLATE_DEBUG :
                    raise
        else :
            self.vtmpl = Variable(path)
    
    def render(self, context):
        tmpl = None

        if self.tmpl :
            tmpl = self.tmpl
        elif self.vtmpl :
            try :
                t = self.vtmpl.resolve(context)
                tmpl = get_template(t)
            except TemplateSyntaxError, e :
                if settings.TEMPLATE_DEBUG :
                    raise
                return ''
            except :
                return ''   # Fail silently for invalid included templates.

        if not tmpl :
            return ''

        update = {}
        for k, v in self.params.items() :
            val = v.resolve(context)
            print "V = ", v, val
            update[k] = val

        context.push()
        context.update(update)
        output = tmpl.render(context)
        context.pop()
        return output

def render_partial(parser, token):
    params = {}

    bits = token.split_contents()
    if len(bits) < 2 :
        raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included" % bits[0])
    try:
        path = bits[1]

        state = 0
        val   = None
        for p in bits[2:] :
            if state == 0 :
                val = p
                state += 1
            elif state == 1 :
                if p.lower() != 'as' :
                    raise TemplateSyntaxError("%r expected format is 'value as name'" % bits[0])
                state += 1
            elif state == 2 :
                params[p] = Variable(val)
                state += 1
            elif state == 3 :
                if p.lower() != 'and' :
                    raise TemplateSyntaxError("%r expected format is 'value as name and'" % bits[0])
                state = 0 
            
    except ValueError:
        raise template.TemplateSyntaxError, '%r tag requires at least a single argument and no spaces in name:value list' % parts[0]

    if path[0] in ('"', "'") and path[0] == path[-1] :
        return PartialNode(path[1:-1], True, params)
    return PartialNode(path, False, params)

render_partial = register.tag('partial', render_partial)

More like this

  1. "Partial Templates" - an alternative to "include" by vigrid 4 years, 3 months ago
  2. More flexible "Partial Template" by robertrv 4 years, 3 months ago
  3. render_partial by hachaboob 4 years, 8 months ago
  4. partial tag by bl4th3rsk1t3 3 years, 11 months ago
  5. Allow any view (probably a generic view) to accept POST variables into extra_context by orblivion 2 years, 6 months ago

Comments

(Forgotten your password?)