Code

Ticket #9093: inclusion_tag_using_template3.diff

File inclusion_tag_using_template3.diff, 4.7 KB (added by exogen@…, 6 years ago)

Fixed diff whitespace, docs typos

Line 
1Index: django/template/__init__.py
2===================================================================
3--- django/template/__init__.py (revision 9050)
4+++ django/template/__init__.py (working copy)
5@@ -823,6 +823,21 @@
6         raise TemplateSyntaxError(message)
7     return node_class(bits)
8 
9+def inclusion_tag_compiler(params, defaults, name, node_class, parser, token):
10+    "Returns an InclusionNode."
11+    bits = token.split_contents()[1:]
12+    using_template = [] # Allow multiple templates via select_template.
13+    try:
14+        using_index = bits.index('using')
15+    except ValueError:
16+        pass
17+    else:
18+        if using_index != len(bits) - 1:
19+            # Get everything after the 'using' keyword.
20+            using_template[:] = bits[using_index + 1:]
21+            bits = bits[:using_index]
22+    return node_class(bits, using_template)
23+
24 class Library(object):
25     def __init__(self):
26         self.filters = {}
27@@ -892,7 +907,7 @@
28         self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
29         return func
30 
31-    def inclusion_tag(self, file_name, context_class=Context, takes_context=False):
32+    def inclusion_tag(self, file_name, context_class=Context, takes_context=False, allow_template_override=True):
33         def dec(func):
34             params, xx, xxx, defaults = getargspec(func)
35             if takes_context:
36@@ -900,9 +915,11 @@
37                     params = params[1:]
38                 else:
39                     raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")
40+            class InclusionNode(Node):
41+                default_template = file_name
42 
43-            class InclusionNode(Node):
44-                def __init__(self, vars_to_resolve):
45+                def __init__(self, vars_to_resolve, using_template=()):
46+                    self.using_template = map(Variable, using_template)
47                     self.vars_to_resolve = map(Variable, vars_to_resolve)
48 
49                 def render(self, context):
50@@ -915,6 +932,8 @@
51                     dict = func(*args)
52 
53                     if not getattr(self, 'nodelist', False):
54+                        using_template = [var.resolve(context) for var in self.using_template]
55+                        file_name = using_template or self.default_template
56                         from django.template.loader import get_template, select_template
57                         if not isinstance(file_name, basestring) and is_iterable(file_name):
58                             t = select_template(file_name)
59@@ -923,8 +942,12 @@
60                         self.nodelist = t.nodelist
61                     return self.nodelist.render(context_class(dict,
62                             autoescape=context.autoescape))
63-
64-            compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
65+           
66+            if allow_template_override:
67+                tag_compiler = inclusion_tag_compiler
68+            else:
69+                tag_compiler = generic_tag_compiler
70+            compile_func = curry(tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
71             compile_func.__doc__ = func.__doc__
72             self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
73             return func
74Index: docs/howto/custom-template-tags.txt
75===================================================================
76--- docs/howto/custom-template-tags.txt (revision 9050)
77+++ docs/howto/custom-template-tags.txt (working copy)
78@@ -706,6 +706,28 @@
79 the tag is passed the context object, as in this example. That's the only
80 difference between this case and the previous ``inclusion_tag`` example.
81 
82+Sometimes you may wish to use an inclusion tag with a template other than the
83+one specified in ``register.inclusion_tag()``. Inclusion tags offer the
84+following syntax for this scenario:
85+
86+.. code-block:: html+django
87+
88+    {% show_results poll using "custom/results.html" %}
89+
90+This will use the template found at ``custom/results.html`` instead of the
91+default of ``results.html`` (specified when the inclusion tag was registered).
92+Multiple templates may be provided with this syntax -- Django's template loader
93+will select which one to use:
94+
95+.. code-block:: html+django
96+
97+    {% show_results poll using "site/results.html" "app/results.html" %}
98+
99+To disallow overriding the template for your inclusion tag, specify
100+``allow_template_override=False`` in ``register.inclusion_tag()``:
101+
102+    register.inclusion_tag('results.html', allow_template_override=False)(show_results)
103+
104 Setting a variable in the context
105 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106