Ticket #16147: 16147.r17335.diff
File 16147.r17335.diff, 10.4 KB (added by , 13 years ago) |
---|
-
django/template/loader_tags.py
diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index 521df2d..93f9018 100644
a b class ExtendsNode(Node): 125 125 # the same. 126 126 return compiled_parent._render(context) 127 127 128 class BaseIncludeNode(Node): 129 def __init__(self, *args, **kwargs): 130 self.extra_context = kwargs.pop('extra_context', {}) 131 self.isolated_context = kwargs.pop('isolated_context', False) 132 super(BaseIncludeNode, self).__init__(*args, **kwargs) 133 134 def render_template(self, template, context): 135 values = dict([(name, var.resolve(context)) for name, var 136 in self.extra_context.iteritems()]) 137 if self.isolated_context: 138 return template.render(context.new(values)) 139 context.update(values) 140 output = template.render(context) 141 context.pop() 142 return output 143 144 class ConstantIncludeNode(BaseIncludeNode): 145 def __init__(self, template_path, *args, **kwargs): 146 super(ConstantIncludeNode, self).__init__(*args, **kwargs) 147 try: 148 t = get_template(template_path) 149 self.template = t 150 except: 151 if settings.TEMPLATE_DEBUG: 152 raise 153 self.template = None 154 155 def render(self, context): 156 if not self.template: 157 return '' 158 return self.render_template(self.template, context) 159 160 class IncludeNode(BaseIncludeNode): 161 def __init__(self, template_name, *args, **kwargs): 162 super(IncludeNode, self).__init__(*args, **kwargs) 128 class IncludeNode(Node): 129 def __init__(self, template_name, resolve=False, *args, **kwargs): 163 130 self.template_name = template_name 131 self.resolve = resolve 132 self.extra_context = kwargs.pop('with', {}) 133 self.isolated_context = kwargs.pop('only', False) 134 super(IncludeNode, self).__init__(*args, **kwargs) 164 135 165 136 def render(self, context): 137 template_name = self.template_name 138 166 139 try: 167 template_name = self.template_name.resolve(context) 140 if self.resolve: 141 template_name = template_name.resolve(context) 142 168 143 template = get_template(template_name) 144 169 145 return self.render_template(template, context) 170 146 except: 171 147 if settings.TEMPLATE_DEBUG: 172 148 raise 173 149 return '' 174 150 151 def render_template(self, template, context): 152 values = dict([(name, var.resolve(context)) for name, var 153 in self.extra_context.iteritems()]) 154 if self.isolated_context: 155 return template.render(context.new(values)) 156 context.update(values) 157 output = template.render(context) 158 context.pop() 159 return output 160 175 161 @register.tag('block') 176 162 def do_block(parser, token): 177 163 """ … … def do_include(parser, token): 243 229 bits = token.split_contents() 244 230 if len(bits) < 2: 245 231 raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0]) 232 246 233 options = {} 247 234 remaining_bits = bits[2:] 248 235 while remaining_bits: … … def do_include(parser, token): 260 247 else: 261 248 raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % 262 249 (bits[0], option)) 263 options[option] = value 264 isolated_context = options.get('only', False) 265 namemap = options.get('with', {}) 266 path = bits[1] 267 if path[0] in ('"', "'") and path[-1] == path[0]: 268 return ConstantIncludeNode(path[1:-1], extra_context=namemap, 269 isolated_context=isolated_context) 270 return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap, 271 isolated_context=isolated_context) 250 options[str(option)] = value 251 252 options.setdefault("only", False) 253 options.setdefault("with", {}) 254 255 template_name = bits[1] 256 if template_name[0] in ('"', "'") and template_name[-1] == template_name[0]: 257 resolve = False 258 template_name = template_name[1:-1] 259 else: 260 resolve = True 261 template_name = parser.compile_filter(template_name) 262 263 return IncludeNode( 264 template_name, 265 resolve=resolve, 266 **options 267 ) -
tests/regressiontests/templates/tests.py
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 1a1b360..5b47d29 100644
a b from django.template import base as template_base, RequestContext, Template, Con 21 21 from django.core import urlresolvers 22 22 from django.template import loader 23 23 from django.template.loaders import app_directories, filesystem, cached 24 from django.test import RequestFactory 24 from django.test import RequestFactory, TestCase 25 25 from django.test.utils import (get_warnings_state, restore_warnings_state, 26 26 setup_test_template_loader, restore_template_loaders, override_settings) 27 27 from django.utils import unittest … … class RequestContextTests(BaseTemplateResponseTest): 1728 1728 template.Template('{% include "child" only %}').render(ctx), 1729 1729 'none' 1730 1730 ) 1731 1732 1733 class IncludeTagTest(TestCase): 1734 1735 def setUp(self): 1736 setup_test_template_loader({ 1737 "basic.html": "Basic", 1738 "headline.html": "{{ headline }}", 1739 "has space.html": "Spaced", 1740 "onetwo.html": "{{ first }}-{{ second }}", 1741 "recursive.html": "{% for item in items %}{{ item.label }}{% if not item.children|length_is:0 %}{% with item.children as items %}({% include 'recursive.html' %}){% endwith %}{% endif %}{% endfor %}", 1742 }) 1743 1744 def tearDown(self): 1745 restore_template_loaders() 1746 1747 def test_include(self): 1748 t = Template("{% include 'basic.html' %}") 1749 c = Context() 1750 output = t.render(c) 1751 self.assertEqual(output, "Basic") 1752 1753 def test_context(self): 1754 t = Template("{% include 'headline.html' %}") 1755 c = Context(dict(headline="Headline")) 1756 output = t.render(c) 1757 self.assertEqual(output, "Headline") 1758 1759 def test_include_variable(self): 1760 t = Template("{% include template_name %}") 1761 c = Context(dict(template_name="basic.html")) 1762 output = t.render(c) 1763 self.assertEqual(output, "Basic") 1764 1765 def test_does_not_exist(self): 1766 t = Template("{% include 'chuck-testa.html' %}") 1767 c = Context() 1768 self.assertEqual(t.render(c), "") 1769 with self.settings(TEMPLATE_DEBUG=True): 1770 with self.assertRaises(template.TemplateDoesNotExist): 1771 t.render(c) 1772 1773 t = Template("{% include template_name %}") 1774 c = Context(dict(template_name="nope.html")) 1775 self.assertEqual(t.render(c), "") 1776 with self.settings(TEMPLATE_DEBUG=True): 1777 with self.assertRaises(template.TemplateDoesNotExist): 1778 t.render(c) 1779 1780 t = Template("{% if false %}{% include 'chuck-testa.html' %}{% endif %}") 1781 c = Context(dict(false=False)) 1782 self.assertEqual(t.render(c), "") 1783 with self.settings(TEMPLATE_DEBUG=True): 1784 self.assertEqual(t.render(c), "") 1785 1786 def test_recursive_include(self): 1787 t = loader.get_template("recursive.html") 1788 c = Context({ 1789 'items': [ 1790 {'label': 1, 'children': [ 1791 {'label': 2, 'children': [ 1792 {'label': 3, 'children': []}, 1793 {'label': 4, 'children': []}, 1794 ]}, 1795 ]}, 1796 ]} 1797 ) 1798 self.assertEqual(t.render(c), "1(2(34))") 1799 1800 def test_with_space(self): 1801 t = Template("{% include 'has space.html' %}") 1802 c = Context() 1803 output = t.render(c) 1804 self.assertEqual(output, "Spaced") 1805 1806 def test_inline_context(self): 1807 t = Template("{% include 'headline.html' with headline='Inline' %}") 1808 c = Context() 1809 output = t.render(c) 1810 self.assertEqual(output, "Inline") 1811 1812 t = Template("{% include headline with headline='Dynamic' %}") 1813 c = Context(dict(headline="headline.html")) 1814 output = t.render(c) 1815 self.assertEqual(output, "Dynamic") 1816 1817 t = Template("{{ headline }} {% include 'headline.html' with headline=headline|upper %}") 1818 c = Context(dict(headline="Headline")) 1819 output = t.render(c) 1820 self.assertEqual(output, "Headline HEADLINE") 1821 1822 def test_isolated_context(self): 1823 t = Template("{% include 'headline.html' only %}") 1824 c = Context(dict(headline="Headline")) 1825 output = t.render(c) 1826 self.assertEqual(output, "") 1827 1828 t = Template("{% include 'onetwo.html' only with first='Inline' %}") 1829 c = Context(dict( 1830 first="First", 1831 second="Second", 1832 )) 1833 output = t.render(c) 1834 self.assertEqual(output, "Inline-") 1835 1836 t = Template("{% include 'onetwo.html' with first='Inline' only %}") 1837 c = Context(dict( 1838 first="First", 1839 second="Second", 1840 )) 1841 output = t.render(c) 1842 self.assertEqual(output, "Inline-") 1843 1844 def test_autoescape_context(self): 1845 t = Template("{% autoescape off %}{% include 'onetwo.html' %}{% endautoescape %}") 1846 c = Context(dict( 1847 first="&", 1848 )) 1849 output = t.render(c) 1850 self.assertEqual(output, "&-") 1851 1852 t = Template("{% autoescape off %}{% include 'onetwo.html' with first=var1 only %}{% endautoescape %}") 1853 c = Context(dict(var1="&")) 1854 output = t.render(c) 1855 self.assertEqual(output, "&-") 1856 1857 def test_errors(self): 1858 with self.assertRaises(template.TemplateSyntaxError): 1859 t = Template("{% include 'onetwo.html' with %}") 1860 1861 with self.assertRaises(template.TemplateSyntaxError): 1862 t = Template("{% include 'onetwo.html' with 'no key' %}") 1863 1864 with self.assertRaises(template.TemplateSyntaxError): 1865 t = Template("{% include 'onetwo.html' with dotted.arg='error' %}") 1866 1867 with self.assertRaises(template.TemplateSyntaxError): 1868 t = Template("{% include 'onetwo.html' with something_random %}") 1869 1870 with self.assertRaises(template.TemplateSyntaxError): 1871 t = Template("{% include 'onetwo.html' with only only %}")