Code

Ticket #3544: rec_include-r6399.diff

File rec_include-r6399.diff, 3.2 KB (added by Flavio Curella <flavio.curella@…>, 7 years ago)

patch updated with new variable resolution

Line 
1Index: /Users/go/working_copies/django/django/template/loader_tags.py
2===================================================================
3--- /Users/go/working_copies/django/django/template/loader_tags.py      (revision 6589)
4+++ /Users/go/working_copies/django/django/template/loader_tags.py      (working copy)
5@@ -1,6 +1,7 @@
6 from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
7-from django.template import Library, Node
8+from django.template import Library, Node, signals
9 from django.template.loader import get_template, get_template_from_string, find_template_source
10+from django.dispatch import dispatcher
11 from django.conf import settings
12 
13 register = Library()
14@@ -113,6 +114,44 @@
15         except:
16             return '' # Fail silently for invalid included templates.
17 
18+class RecursiveIncludeNode(Node):
19+    cache = {}
20+    @staticmethod
21+    def _get_template(template_name):
22+        if not RecursiveIncludeNode._has_template(template_name):
23+            RecursiveIncludeNode._load_template(template_name)
24+        return RecursiveIncludeNode.cache[template_name]
25+    @staticmethod
26+    def _has_template(template_name):
27+        return RecursiveIncludeNode.cache.has_key(template_name)
28+    @staticmethod
29+    def _load_template(template_name):
30+        RecursiveIncludeNode.cache[template_name] = None
31+        try:
32+            RecursiveIncludeNode.cache[template_name] = get_template(template_name)
33+        except:
34+            del RecursiveIncludeNode.cache[template_name]
35+            raise
36+    def __init__(self, template_name):
37+        self.template_name = Variable(template_name)
38+    def render(self, context):
39+        try:
40+            template_name = self.template_name.resolve(context)
41+            t = RecursiveIncludeNode._get_template(template_name)
42+            return t.render(context)
43+        except TemplateSyntaxError, e:
44+            if settings.TEMPLATE_DEBUG:
45+                raise
46+            return ''
47+        except:
48+            return '' # Fail silently for invalid included templates.
49+
50+def clear_template_include_cache():
51+    RecursiveIncludeNode.cache = {}
52+
53+dispatcher.connect(clear_template_include_cache, signal=signals.request_finished)
54+dispatcher.connect(clear_template_include_cache, signal=signals.got_request_exception)
55+
56 def do_block(parser, token):
57     """
58     Define a block that can be overridden by child templates.
59@@ -171,7 +210,20 @@
60     if path[0] in ('"', "'") and path[-1] == path[0]:
61         return ConstantIncludeNode(path[1:-1])
62     return IncludeNode(bits[1])
63+   
64+def rec_include(parser, token):
65+    bits = token.contents.split()
66+    if len(bits) != 2:
67+        raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
68+    path = bits[1]
69+    from django.template.loader_tags import IncludeNode
70+    if path[0] in ('"', "'") and path[-1] == path[0]:
71+        template_name = path[1:-1]
72+        if not RecursiveIncludeNode._has_template(template_name):
73+            RecursiveIncludeNode._load_template(template_name)
74+    return RecursiveIncludeNode(bits[1])
75 
76 register.tag('block', do_block)
77 register.tag('extends', do_extends)
78 register.tag('include', do_include)
79+register.tag('rec_include', rec_include)