mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #17660 -- Standardize extends tag token parsing
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17568 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -1,5 +1,6 @@ | |||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.template.base import TemplateSyntaxError, Library, Node, TextNode, token_kwargs | from django.template.base import TemplateSyntaxError, Library, Node, TextNode,\ | ||||||
|  |     token_kwargs, Variable | ||||||
| from django.template.loader import get_template | from django.template.loader import get_template | ||||||
| from django.utils.safestring import mark_safe | from django.utils.safestring import mark_safe | ||||||
|  |  | ||||||
| @@ -74,26 +75,23 @@ class BlockNode(Node): | |||||||
| class ExtendsNode(Node): | class ExtendsNode(Node): | ||||||
|     must_be_first = True |     must_be_first = True | ||||||
|  |  | ||||||
|     def __init__(self, nodelist, parent_name, parent_name_expr, template_dirs=None): |     def __init__(self, nodelist, parent_name, template_dirs=None): | ||||||
|         self.nodelist = nodelist |         self.nodelist = nodelist | ||||||
|         self.parent_name, self.parent_name_expr = parent_name, parent_name_expr |         self.parent_name = parent_name | ||||||
|         self.template_dirs = template_dirs |         self.template_dirs = template_dirs | ||||||
|         self.blocks = dict([(n.name, n) for n in nodelist.get_nodes_by_type(BlockNode)]) |         self.blocks = dict([(n.name, n) for n in nodelist.get_nodes_by_type(BlockNode)]) | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         if self.parent_name_expr: |         return '<ExtendsNode: extends %s>' % self.parent_name.token | ||||||
|             return "<ExtendsNode: extends %s>" % self.parent_name_expr.token |  | ||||||
|         return '<ExtendsNode: extends "%s">' % self.parent_name |  | ||||||
|  |  | ||||||
|     def get_parent(self, context): |     def get_parent(self, context): | ||||||
|         if self.parent_name_expr: |         parent = self.parent_name.resolve(context) | ||||||
|             parent = self.parent_name_expr.resolve(context) |  | ||||||
|         else: |  | ||||||
|             parent = self.parent_name |  | ||||||
|         if not parent: |         if not parent: | ||||||
|             error_msg = "Invalid template name in 'extends' tag: %r." % parent |             error_msg = "Invalid template name in 'extends' tag: %r." % parent | ||||||
|             if self.parent_name_expr: |             if self.parent_name.filters or\ | ||||||
|                 error_msg += " Got this from the '%s' variable." % self.parent_name_expr.token |                     isinstance(self.parent_name.var, Variable): | ||||||
|  |                 error_msg += " Got this from the '%s' variable." %\ | ||||||
|  |                     self.parent_name.token | ||||||
|             raise TemplateSyntaxError(error_msg) |             raise TemplateSyntaxError(error_msg) | ||||||
|         if hasattr(parent, 'render'): |         if hasattr(parent, 'render'): | ||||||
|             return parent # parent is a Template object |             return parent # parent is a Template object | ||||||
| @@ -212,15 +210,11 @@ def do_extends(parser, token): | |||||||
|     bits = token.split_contents() |     bits = token.split_contents() | ||||||
|     if len(bits) != 2: |     if len(bits) != 2: | ||||||
|         raise TemplateSyntaxError("'%s' takes one argument" % bits[0]) |         raise TemplateSyntaxError("'%s' takes one argument" % bits[0]) | ||||||
|     parent_name, parent_name_expr = None, None |     parent_name = parser.compile_filter(bits[1]) | ||||||
|     if bits[1][0] in ('"', "'") and bits[1][-1] == bits[1][0]: |  | ||||||
|         parent_name = bits[1][1:-1] |  | ||||||
|     else: |  | ||||||
|         parent_name_expr = parser.compile_filter(bits[1]) |  | ||||||
|     nodelist = parser.parse() |     nodelist = parser.parse() | ||||||
|     if nodelist.get_nodes_by_type(ExtendsNode): |     if nodelist.get_nodes_by_type(ExtendsNode): | ||||||
|         raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0]) |         raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0]) | ||||||
|     return ExtendsNode(nodelist, parent_name, parent_name_expr) |     return ExtendsNode(nodelist, parent_name) | ||||||
|  |  | ||||||
| @register.tag('include') | @register.tag('include') | ||||||
| def do_include(parser, token): | def do_include(parser, token): | ||||||
|   | |||||||
| @@ -1031,6 +1031,17 @@ If you depended on the output of this command -- if you parsed it, for example | |||||||
| management commands in a script, use | management commands in a script, use | ||||||
| :djadmin:`manage.py help --commands <help>` instead. | :djadmin:`manage.py help --commands <help>` instead. | ||||||
|  |  | ||||||
|  | ``extends`` template tag | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | Previously, the :ttag:`extends` tag used a buggy method of parsing arguments, | ||||||
|  | which could lead to it erroneously considering an argument as a string literal | ||||||
|  | when it wasn't.  It now utilises ``parser.compile_filter`` like other tags. | ||||||
|  |  | ||||||
|  | The internals of the tag aren't part of the official stable API, but in the | ||||||
|  | interests of full disclosure, the ``ExtendsNode.__init__`` definition has | ||||||
|  | changed which may break any custom tags that use this node class. | ||||||
|  |  | ||||||
| Features deprecated in 1.4 | Features deprecated in 1.4 | ||||||
| ========================== | ========================== | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1204,6 +1204,9 @@ class Templates(unittest.TestCase): | |||||||
|             'inheritance40': ("{% extends 'inheritance33' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': 1}, '1new23'), |             'inheritance40': ("{% extends 'inheritance33' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': 1}, '1new23'), | ||||||
|             'inheritance41': ("{% extends 'inheritance36' %}{% block opt %}new{{ block.super }}{% endblock %}", {'numbers': '123'}, '_new1_new2_new3_'), |             'inheritance41': ("{% extends 'inheritance36' %}{% block opt %}new{{ block.super }}{% endblock %}", {'numbers': '123'}, '_new1_new2_new3_'), | ||||||
|  |  | ||||||
|  |             # Expression starting and ending with a quote | ||||||
|  |             'inheritance42': ("{% extends 'inheritance02'|cut:' ' %}", {}, '1234'), | ||||||
|  |  | ||||||
|             ### LOADING TAG LIBRARIES ################################################# |             ### LOADING TAG LIBRARIES ################################################# | ||||||
|             'load01': ("{% load testtags subpackage.echo %}{% echo test %} {% echo2 \"test\" %}", {}, "test test"), |             'load01': ("{% load testtags subpackage.echo %}{% echo test %} {% echo2 \"test\" %}", {}, "test test"), | ||||||
|             'load02': ("{% load subpackage.echo %}{% echo2 \"test\" %}", {}, "test"), |             'load02': ("{% load subpackage.echo %}{% echo2 \"test\" %}", {}, "test"), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user