mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #26402 -- Added relative path support in include/extends template tags.
This commit is contained in:
committed by
Tim Graham
parent
ad403ffa45
commit
aec4f97555
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import posixpath
|
||||
from collections import defaultdict
|
||||
|
||||
from django.utils import six
|
||||
@@ -249,6 +250,36 @@ def do_block(parser, token):
|
||||
return BlockNode(block_name, nodelist)
|
||||
|
||||
|
||||
def construct_relative_path(current_template_name, relative_name):
|
||||
"""
|
||||
Convert a relative path (starting with './' or '../') to the full template
|
||||
name based on the current_template_name.
|
||||
"""
|
||||
if not any(relative_name.startswith(x) for x in ["'./", "'../", '"./', '"../']):
|
||||
# relative_name is a variable or a literal that doesn't contain a
|
||||
# relative path.
|
||||
return relative_name
|
||||
|
||||
new_name = posixpath.normpath(
|
||||
posixpath.join(
|
||||
posixpath.dirname(current_template_name.lstrip('/')),
|
||||
relative_name.strip('\'"')
|
||||
)
|
||||
)
|
||||
if new_name.startswith('../'):
|
||||
raise TemplateSyntaxError(
|
||||
"The relative path '%s' points outside the file hierarchy that "
|
||||
"template '%s' is in." % (relative_name, current_template_name)
|
||||
)
|
||||
if current_template_name.lstrip('/') == new_name:
|
||||
raise TemplateSyntaxError(
|
||||
"The relative path '%s' was translated to template name '%s', the "
|
||||
"same template in which the tag appears."
|
||||
% (relative_name, current_template_name)
|
||||
)
|
||||
return '"%s"' % new_name
|
||||
|
||||
|
||||
@register.tag('extends')
|
||||
def do_extends(parser, token):
|
||||
"""
|
||||
@@ -263,6 +294,7 @@ def do_extends(parser, token):
|
||||
bits = token.split_contents()
|
||||
if len(bits) != 2:
|
||||
raise TemplateSyntaxError("'%s' takes one argument" % bits[0])
|
||||
bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
|
||||
parent_name = parser.compile_filter(bits[1])
|
||||
nodelist = parser.parse()
|
||||
if nodelist.get_nodes_by_type(ExtendsNode):
|
||||
@@ -313,5 +345,6 @@ def do_include(parser, token):
|
||||
options[option] = value
|
||||
isolated_context = options.get('only', False)
|
||||
namemap = options.get('with', {})
|
||||
bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
|
||||
return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap,
|
||||
isolated_context=isolated_context)
|
||||
|
||||
Reference in New Issue
Block a user