Fixed #32290 -- Fixed TemplateNotFound in {% include %} tag for relative path in variable.

This commit is contained in:
Hasan Ramezani 2020-12-27 21:21:59 +01:00 committed by Mariusz Felisiak
parent 640a6e1dce
commit c978dd93fd
3 changed files with 19 additions and 4 deletions

View File

@ -171,7 +171,10 @@ class IncludeNode(Node):
# If not, try the cache and select_template(). # If not, try the cache and select_template().
template_name = template or () template_name = template or ()
if isinstance(template_name, str): if isinstance(template_name, str):
template_name = (template_name,) template_name = (construct_relative_path(
self.origin.template_name,
template_name,
),)
else: else:
template_name = tuple(template_name) template_name = tuple(template_name)
cache = context.render_context.dicts[0].setdefault(self, {}) cache = context.render_context.dicts[0].setdefault(self, {})
@ -226,7 +229,12 @@ def construct_relative_path(current_template_name, relative_name):
Convert a relative path (starting with './' or '../') to the full template Convert a relative path (starting with './' or '../') to the full template
name based on the current_template_name. name based on the current_template_name.
""" """
if not relative_name.startswith(("'./", "'../", '"./', '"../')): has_quotes = (
(relative_name.startswith('"') and relative_name.endswith('"')) or
(relative_name.startswith("'") and relative_name.endswith("'"))
)
new_name = relative_name.strip('\'"')
if not new_name.startswith(('./', '../')):
# relative_name is a variable or a literal that doesn't contain a # relative_name is a variable or a literal that doesn't contain a
# relative path. # relative path.
return relative_name return relative_name
@ -234,7 +242,7 @@ def construct_relative_path(current_template_name, relative_name):
new_name = posixpath.normpath( new_name = posixpath.normpath(
posixpath.join( posixpath.join(
posixpath.dirname(current_template_name.lstrip('/')), posixpath.dirname(current_template_name.lstrip('/')),
relative_name.strip('\'"') new_name,
) )
) )
if new_name.startswith('../'): if new_name.startswith('../'):
@ -248,7 +256,7 @@ def construct_relative_path(current_template_name, relative_name):
"same template in which the tag appears." "same template in which the tag appears."
% (relative_name, current_template_name) % (relative_name, current_template_name)
) )
return '"%s"' % new_name return f'"{new_name}"' if has_quotes else new_name
@register.tag('extends') @register.tag('extends')

View File

@ -0,0 +1 @@
{% include tmpl %}

View File

@ -70,6 +70,12 @@ class IncludeRelativeBehaviorTests(SimpleTestCase):
output = template.render(Context({})) output = template.render(Context({}))
self.assertEqual(output.strip(), 'dir2 include') self.assertEqual(output.strip(), 'dir2 include')
def test_normal_include_variable(self):
engine = Engine(dirs=[RELATIVE])
template = engine.get_template('dir1/dir2/inc3.html')
output = template.render(Context({'tmpl': './include_content.html'}))
self.assertEqual(output.strip(), 'dir2 include')
def test_dir2_include(self): def test_dir2_include(self):
engine = Engine(dirs=[RELATIVE]) engine = Engine(dirs=[RELATIVE])
template = engine.get_template('dir1/dir2/inc1.html') template = engine.get_template('dir1/dir2/inc1.html')