Ticket #16147: 16147.r17335.diff

File 16147.r17335.diff, 10.4 KB (added by Preston Timmons, 8 years ago)

Updated patch @r17335

  • 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): 
    125125        # the same.
    126126        return compiled_parent._render(context)
    127127
    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)
     128class IncludeNode(Node):
     129    def __init__(self, template_name, resolve=False, *args, **kwargs):
    163130        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)
    164135
    165136    def render(self, context):
     137        template_name = self.template_name
     138
    166139        try:
    167             template_name = self.template_name.resolve(context)
     140            if self.resolve:
     141                template_name = template_name.resolve(context)
     142
    168143            template = get_template(template_name)
     144
    169145            return self.render_template(template, context)
    170146        except:
    171147            if settings.TEMPLATE_DEBUG:
    172148                raise
    173149            return ''
    174150
     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
    175161@register.tag('block')
    176162def do_block(parser, token):
    177163    """
    def do_include(parser, token): 
    243229    bits = token.split_contents()
    244230    if len(bits) < 2:
    245231        raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0])
     232
    246233    options = {}
    247234    remaining_bits = bits[2:]
    248235    while remaining_bits:
    def do_include(parser, token): 
    260247        else:
    261248            raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
    262249                                      (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 
    2121from django.core import urlresolvers
    2222from django.template import loader
    2323from django.template.loaders import app_directories, filesystem, cached
    24 from django.test import RequestFactory
     24from django.test import RequestFactory, TestCase
    2525from django.test.utils import (get_warnings_state, restore_warnings_state,
    2626    setup_test_template_loader, restore_template_loaders, override_settings)
    2727from django.utils import unittest
    class RequestContextTests(BaseTemplateResponseTest): 
    17281728            template.Template('{% include "child" only %}').render(ctx),
    17291729            'none'
    17301730        )
     1731
     1732
     1733class 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 %}")
Back to Top