mirror of https://github.com/django/django.git
Fixed #20995 -- Added support for iterables of template names to {% include %} template tag.
Thanks Adam Johnson for the review.
This commit is contained in:
parent
8690878507
commit
f37d548ede
|
@ -168,12 +168,16 @@ class IncludeNode(Node):
|
||||||
template = self.template.resolve(context)
|
template = self.template.resolve(context)
|
||||||
# Does this quack like a Template?
|
# Does this quack like a Template?
|
||||||
if not callable(getattr(template, 'render', None)):
|
if not callable(getattr(template, 'render', None)):
|
||||||
# If not, try the cache and get_template().
|
# If not, try the cache and select_template().
|
||||||
template_name = template
|
template_name = template or ()
|
||||||
|
if isinstance(template_name, str):
|
||||||
|
template_name = (template_name,)
|
||||||
|
else:
|
||||||
|
template_name = tuple(template_name)
|
||||||
cache = context.render_context.dicts[0].setdefault(self, {})
|
cache = context.render_context.dicts[0].setdefault(self, {})
|
||||||
template = cache.get(template_name)
|
template = cache.get(template_name)
|
||||||
if template is None:
|
if template is None:
|
||||||
template = context.template.engine.get_template(template_name)
|
template = context.template.engine.select_template(template_name)
|
||||||
cache[template_name] = template
|
cache[template_name] = template
|
||||||
# Use the base.Template of a backends.django.Template.
|
# Use the base.Template of a backends.django.Template.
|
||||||
elif hasattr(template, 'template'):
|
elif hasattr(template, 'template'):
|
||||||
|
|
|
@ -688,6 +688,10 @@ the variable ``template_name``::
|
||||||
The variable may also be any object with a ``render()`` method that accepts a
|
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.
|
context. This allows you to reference a compiled ``Template`` in your context.
|
||||||
|
|
||||||
|
Additionally, the variable may be an iterable of template names, in which case
|
||||||
|
the first that can be loaded will be used, as per
|
||||||
|
:func:`~django.template.loader.select_template`.
|
||||||
|
|
||||||
An included template is rendered within the context of the template that
|
An included template is rendered within the context of the template that
|
||||||
includes it. This example produces the output ``"Hello, John!"``:
|
includes it. This example produces the output ``"Hello, John!"``:
|
||||||
|
|
||||||
|
@ -724,6 +728,10 @@ available to the included template::
|
||||||
been evaluated and rendered* - not blocks that can be overridden by, for
|
been evaluated and rendered* - not blocks that can be overridden by, for
|
||||||
example, an extending template.
|
example, an extending template.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
|
Support for iterables of template names was added.
|
||||||
|
|
||||||
.. templatetag:: load
|
.. templatetag:: load
|
||||||
|
|
||||||
``load``
|
``load``
|
||||||
|
|
|
@ -322,6 +322,8 @@ Templates
|
||||||
and :ttag:`blocktrans` template tags aliases continue to work, and will be
|
and :ttag:`blocktrans` template tags aliases continue to work, and will be
|
||||||
retained for the foreseeable future.
|
retained for the foreseeable future.
|
||||||
|
|
||||||
|
* The :ttag:`include` template tag now accepts iterables of template names.
|
||||||
|
|
||||||
Tests
|
Tests
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,26 @@ class IncludeTests(SimpleTestCase):
|
||||||
output = outer_tmpl.render(ctx)
|
output = outer_tmpl.render(ctx)
|
||||||
self.assertEqual(output, 'This worked!')
|
self.assertEqual(output, 'This worked!')
|
||||||
|
|
||||||
|
def test_include_template_iterable(self):
|
||||||
|
engine = Engine.get_default()
|
||||||
|
outer_temp = engine.from_string('{% include var %}')
|
||||||
|
tests = [
|
||||||
|
('admin/fail.html', 'index.html'),
|
||||||
|
['admin/fail.html', 'index.html'],
|
||||||
|
]
|
||||||
|
for template_names in tests:
|
||||||
|
with self.subTest(template_names):
|
||||||
|
output = outer_temp.render(Context({'var': template_names}))
|
||||||
|
self.assertEqual(output, 'index\n')
|
||||||
|
|
||||||
|
def test_include_template_none(self):
|
||||||
|
engine = Engine.get_default()
|
||||||
|
outer_temp = engine.from_string('{% include var %}')
|
||||||
|
ctx = Context({'var': None})
|
||||||
|
msg = 'No template names provided'
|
||||||
|
with self.assertRaisesMessage(TemplateDoesNotExist, msg):
|
||||||
|
outer_temp.render(ctx)
|
||||||
|
|
||||||
def test_include_from_loader_get_template(self):
|
def test_include_from_loader_get_template(self):
|
||||||
tmpl = loader.get_template('include_tpl.html') # {% include tmpl %}
|
tmpl = loader.get_template('include_tpl.html') # {% include tmpl %}
|
||||||
output = tmpl.render({'tmpl': loader.get_template('index.html')})
|
output = tmpl.render({'tmpl': loader.get_template('index.html')})
|
||||||
|
|
Loading…
Reference in New Issue