From 5cdacbda034af928f5033c9afc7b50ee0b13f75c Mon Sep 17 00:00:00 2001 From: Curtis Maloney Date: Wed, 28 Aug 2013 22:17:20 +1000 Subject: [PATCH] Fixed #17356 -- Allowed {% include %} to render compiled templates Reviewed by Loic Bistuer and Tim Graham. --- django/template/loader_tags.py | 7 +++++-- docs/ref/templates/builtins.txt | 6 ++++++ docs/releases/1.7.txt | 5 +++++ tests/template_tests/tests.py | 11 +++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index d48f85eb35b..224efe884ba 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -159,8 +159,11 @@ class IncludeNode(BaseIncludeNode): def render(self, context): try: - template_name = self.template_name.resolve(context) - template = get_template(template_name) + template = self.template_name.resolve(context) + # Does this quack like a Template? + if not callable(getattr(template, 'render', None)): + # If not, we'll try get_template + template = get_template(template) return self.render_template(template, context) except: if settings.TEMPLATE_DEBUG: diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 5b02ab22d1c..767906cd8b7 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -691,6 +691,12 @@ the variable ``template_name``:: {% include template_name %} +.. versionchanged:: 1.7 + + The variable may also be any object with a ``render()`` method that + accepts a context. This allows you to reference a compiled ``Template`` in + your context. + An included template is rendered with the context of the template that's including it. This example produces the output ``"Hello, John"``: diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 2bf7c0258f7..d0c3be16887 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -258,6 +258,11 @@ Templates * The :ttag:`widthratio` template tag now accepts an "as" parameter to capture the result in a variable. +* The :ttag:`include` template tag will now also accept anything with a + ``render()`` method (such as a ``Template``) as an argument. String + arguments will be looked up using + :func:`~django.template.loader.get_template` as always. + Backwards incompatible changes in 1.7 ===================================== diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index 034280f08d2..c2179b43c10 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -338,6 +338,17 @@ class TemplateLoaderTests(TestCase): loader.template_source_loaders = old_loaders settings.TEMPLATE_DEBUG = old_td + def test_include_template_argument(self): + """ + Support any render() supporting object + """ + ctx = Context({ + 'tmpl': Template('This worked!'), + }) + outer_tmpl = Template('{% include tmpl %}') + output = outer_tmpl.render(ctx) + self.assertEqual(output, 'This worked!') + class TemplateRegressionTests(TestCase):