Code

Ticket #1105: simple_tag_r1785.diff

File simple_tag_r1785.diff, 3.1 KB (added by django@…, 9 years ago)

simple_tag enhancement

Line 
1Index: django/core/template/__init__.py
2===================================================================
3--- django/core/template/__init__.py    (revision 1785)
4+++ django/core/template/__init__.py    (working copy)
5@@ -775,7 +775,7 @@
6             raise
7         return self.encode_output(output)
8 
9-def generic_tag_compiler(params, defaults, name, node_class, parser, token):
10+def generic_tag_compiler(params, defaults, name, node_class, parser, token, takes_context=False, takes_block=False):
11     "Returns a template.Node subclass."
12     bits = token.contents.split()[1:]
13     bmax = len(params)
14@@ -787,6 +787,12 @@
15         else:
16             message = "%s takes between %s and %s arguments" % (name, bmin, bmax)
17         raise TemplateSyntaxError, message
18+    if takes_context:
19+        node_class = curry(node_class, takes_context=takes_context)
20+    if takes_block:
21+        nodelist = parser.parse(('end' + name,))
22+        parser.delete_first_token()
23+        node_class = curry(node_class, block_nodelist=nodelist)
24     return node_class(bits)
25 
26 class Library(object):
27@@ -842,18 +848,32 @@
28         self.filters[func.__name__] = func
29         return func
30 
31-    def simple_tag(self,func):
32-        (params, xx, xxx, defaults) = getargspec(func)
33+    def simple_tag(self, compile_function=None, takes_block=False, takes_context=False):
34+        if compile_function == None:
35+            return curry(self.simple_tag_function, takes_block=takes_block, takes_context=takes_context)
36+        elif callable(compile_function):
37+            return self.simple_tag_function(compile_function, takes_block=takes_block, takes_context=takes_context)
38+        else:
39+            raise InvalidTemplateLibrary, "Unsupported argument to Library.simple_tag: (%r)", (compile_function,)
40 
41+    def simple_tag_function(self, func, takes_block=False, takes_context=False):
42         class SimpleNode(Node):
43-            def __init__(self, vars_to_resolve):
44+            def __init__(self, vars_to_resolve, takes_context=False, block_nodelist=None):
45                 self.vars_to_resolve = vars_to_resolve
46+                self.takes_context, self.block_nodelist = takes_context, block_nodelist
47 
48             def render(self, context):
49                 resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve]
50-                return func(*resolved_vars)
51+                if self.block_nodelist:
52+                    resolved_vars.insert(0, self.block_nodelist)
53+                if self.takes_context:
54+                    resolved_vars.insert(0, context)
55+                rendered = func(*resolved_vars)
56+                return rendered or ''
57 
58-        compile_func = curry(generic_tag_compiler, params, defaults, func.__name__, SimpleNode)
59+        (params, xx, xxx, defaults) = getargspec(func)
60+        taken_args = sum([takes_block, takes_context])
61+        compile_func = curry(generic_tag_compiler, params[taken_args:], defaults, func.__name__, SimpleNode, takes_block=takes_block, takes_context=takes_context)
62         compile_func.__doc__ = func.__doc__
63         self.tag(func.__name__, compile_func)
64         return func