1
+ from django .template .loader_tags import BlockNode , ExtendsNode
2
+ from django .template import loader , Context , RequestContext
3
+
4
+
5
+
6
+ class BlockNotFound (Exception ):
7
+ pass
8
+
9
+
10
+ def get_template (template ):
11
+ if isinstance (template , (tuple , list )):
12
+ return loader .select_template (template )
13
+ return loader .get_template (template )
14
+
15
+ def render_template_blocks (template , block_list , context ):
16
+ """
17
+ Renders a single block from a template. This template should have previously been rendered.
18
+ """
19
+ return render_template_blocks_nodelist (template .nodelist , block_list , context )
20
+
21
+ def render_template_blocks_nodelist (nodelist , block_list , context ):
22
+ block_map = {}
23
+
24
+ for node in nodelist :
25
+ if isinstance (node , BlockNode ) and node .name in block_list :
26
+ block_map .setdefault (node .name , node .render (context ))
27
+
28
+ for key in ('nodelist' , 'nodelist_true' , 'nodelist_false' ):
29
+ if hasattr (node , key ):
30
+ try :
31
+ inner_block_map = render_template_block_nodelist (getattr (node , key ), block_list , context )
32
+ except :
33
+ pass
34
+ else :
35
+ block_map .update (inner_block_map )
36
+ inner_block_map = {}
37
+
38
+ for node in nodelist :
39
+ if isinstance (node , ExtendsNode ):
40
+ try :
41
+ inner_block_map = render_template_block (node .get_parent (context ), block_list , context )
42
+ except BlockNotFound :
43
+ pass
44
+ else :
45
+ block_map .update (inner_block_map )
46
+
47
+ return block_map
48
+
49
+ def render_block_to_string (template_name , block_list , dictionary = {}, context_instance = None ):
50
+ """
51
+ Loads the given template_name and renders the given block with the given dictionary as
52
+ context. Returns a string.
53
+ """
54
+ dictionary = dictionary or {}
55
+ template = get_template (template_name )
56
+
57
+ if context_instance is not None :
58
+ context_instance .update (dictionary )
59
+ else :
60
+ context_instance = Context (dictionary )
61
+
62
+ template .render (context_instance )
63
+
64
+ return render_template_block (template , block_list , context_instance )
65
+
66
+ def direct_block_to_template (request , template , block , extra_context = None , mimetype = None , ** kwargs ):
67
+ """
68
+ Render a given block in a given template with any extra URL parameters in the context as
69
+ ``{{ params }}``.
70
+ """
71
+ if extra_context is None :
72
+ extra_context = {}
73
+ dictionary = {'params' : kwargs }
74
+ for key , value in extra_context .items ():
75
+ if callable (value ):
76
+ dictionary [key ] = value ()
77
+ else :
78
+ dictionary [key ] = value
79
+ c = RequestContext (request , dictionary )
80
+ t = get_template (template )
81
+ t .render (c )
82
+ return HttpResponse (render_template_block (t , block , c ), mimetype = mimetype )
0 commit comments