Code

Ticket #6834: loader_tags.diff

File loader_tags.diff, 5.2 KB (added by durin42, 6 years ago)
Line 
1Index: django/template/loader_tags.py
2===================================================================
3--- django/template/loader_tags.py      (revision 7317)
4+++ django/template/loader_tags.py      (working copy)
5@@ -39,10 +39,11 @@
6 class ExtendsNode(Node):
7     must_be_first = True
8 
9-    def __init__(self, nodelist, parent_name, parent_name_expr, template_dirs=None):
10+    def __init__(self, nodelist, parent_name, parent_name_expr,
11+                 template_dirs_expr=None):
12         self.nodelist = nodelist
13         self.parent_name, self.parent_name_expr = parent_name, parent_name_expr
14-        self.template_dirs = template_dirs
15+        self.template_dirs_expr = template_dirs_expr
16 
17     def __repr__(self):
18         if self.parent_name_expr:
19@@ -53,6 +54,9 @@
20         if self.parent_name_expr:
21             self.parent_name = self.parent_name_expr.resolve(context)
22         parent = self.parent_name
23+        template_dirs = None
24+        if self.template_dirs_expr:
25+            template_dirs = self.template_dirs_expr.resolve(context)
26         if not parent:
27             error_msg = "Invalid template name in 'extends' tag: %r." % parent
28             if self.parent_name_expr:
29@@ -61,7 +65,7 @@
30         if hasattr(parent, 'render'):
31             return parent # parent is a Template object
32         try:
33-            source, origin = find_template_source(parent, self.template_dirs)
34+            source, origin = find_template_source(parent, template_dirs)
35         except TemplateDoesNotExist:
36             raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent
37         else:
38@@ -93,9 +97,9 @@
39         return compiled_parent.render(context)
40 
41 class ConstantIncludeNode(Node):
42-    def __init__(self, template_path):
43+    def __init__(self, template_path, dirs=None):
44         try:
45-            t = get_template(template_path)
46+            t = get_template(template_path, dirs)
47             self.template = t
48         except:
49             if settings.TEMPLATE_DEBUG:
50@@ -109,13 +113,14 @@
51             return ''
52 
53 class IncludeNode(Node):
54-    def __init__(self, template_name):
55+    def __init__(self, template_name, dirs=None):
56         self.template_name = Variable(template_name)
57+        self.dirs = dirs
58 
59     def render(self, context):
60         try:
61             template_name = self.template_name.resolve(context)
62-            t = get_template(template_name)
63+            t = get_template(template_name, dirs)
64             return t.render(context)
65         except TemplateSyntaxError, e:
66             if settings.TEMPLATE_DEBUG:
67@@ -153,19 +158,26 @@
68     or ``{% extends variable %}`` uses the value of ``variable`` as either the
69     name of the parent template to extend (if it evaluates to a string) or as
70     the parent tempate itelf (if it evaluates to a Template object).
71+   
72+    This tag accepts an optional second argument which, if provided and not a
73+    variable which is None, will override the settings.TEMPLATE_DIRS value.
74+    If provided, it should be a variable which is a list of directories.
75     """
76     bits = token.contents.split()
77-    if len(bits) != 2:
78-        raise TemplateSyntaxError, "'%s' takes one argument" % bits[0]
79+    if len(bits) != 2 and len(bits) != 3:
80+        raise TemplateSyntaxError, "'%s' takes one or two arguments" % bits[0]
81     parent_name, parent_name_expr = None, None
82+    dirs_expr = None
83     if bits[1][0] in ('"', "'") and bits[1][-1] == bits[1][0]:
84         parent_name = bits[1][1:-1]
85     else:
86         parent_name_expr = parser.compile_filter(bits[1])
87+    if len(bits) == 3:
88+        dirs_expr = parser.compile_filter(bits[2])
89     nodelist = parser.parse()
90     if nodelist.get_nodes_by_type(ExtendsNode):
91         raise TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0]
92-    return ExtendsNode(nodelist, parent_name, parent_name_expr)
93+    return ExtendsNode(nodelist, parent_name, parent_name_expr, dirs_expr)
94 
95 def do_include(parser, token):
96     """
97@@ -176,12 +188,15 @@
98         {% include "foo/some_include" %}
99     """
100     bits = token.contents.split()
101-    if len(bits) != 2:
102+    if len(bits) != 2 and len(bits) != 3:
103         raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
104     path = bits[1]
105+    dirs_expr = None
106+    if len(bits) == 3:
107+        dirs_expr = parser.compile_filter(bits[2])
108     if path[0] in ('"', "'") and path[-1] == path[0]:
109-        return ConstantIncludeNode(path[1:-1])
110-    return IncludeNode(bits[1])
111+        return ConstantIncludeNode(path[1:-1], dirs_expr)
112+    return IncludeNode(bits[1], dirs_expr)
113 
114 register.tag('block', do_block)
115 register.tag('extends', do_extends)
116Index: docs/templates.txt
117===================================================================
118--- docs/templates.txt  (revision 7317)
119+++ docs/templates.txt  (working copy)
120@@ -646,6 +646,10 @@
121      parent template. If the variable evaluates to a ``Template`` object,
122      Django will use that object as the parent template.
123 
124+``{% extends "name" template_paths %}`` works for either of the above two ways,
125+but will use the variable ``template_paths`` to provide the list of directories
126+in which to search for templates.
127+
128 See `Template inheritance`_ for more information.
129 
130 filter