Fixed #501 -- Fixed block.super in multi-level templates, and added unit tests to confirm. Thanks for the patch, django@kieranholland.com
git-svn-id: http://code.djangoproject.com/svn/django/trunk@715 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
26021249a4
commit
8a7189f38f
|
@ -42,32 +42,33 @@ def select_template(template_name_list):
|
||||||
# If we get here, none of the templates could be loaded
|
# If we get here, none of the templates could be loaded
|
||||||
raise template.TemplateDoesNotExist, ', '.join(template_name_list)
|
raise template.TemplateDoesNotExist, ', '.join(template_name_list)
|
||||||
|
|
||||||
class SuperBlock:
|
|
||||||
"This implements the ability for {{ block.super }} to render the parent block's contents"
|
|
||||||
def __init__(self, context, nodelist):
|
|
||||||
self.context, self.nodelist = context, nodelist
|
|
||||||
|
|
||||||
def super(self):
|
|
||||||
if self.nodelist:
|
|
||||||
return self.nodelist.render(self.context)
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
class BlockNode(template.Node):
|
class BlockNode(template.Node):
|
||||||
def __init__(self, name, nodelist):
|
def __init__(self, name, nodelist, parent=None):
|
||||||
self.name, self.nodelist = name, nodelist
|
self.name, self.nodelist, self.parent = name, nodelist, parent
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist)
|
return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
context.push()
|
context.push()
|
||||||
nodelist = hasattr(self, 'original_node_list') and self.original_node_list or None
|
# Save context in case of block.super().
|
||||||
context['block'] = SuperBlock(context, nodelist)
|
self.context = context
|
||||||
|
context['block'] = self
|
||||||
result = self.nodelist.render(context)
|
result = self.nodelist.render(context)
|
||||||
context.pop()
|
context.pop()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def super(self):
|
||||||
|
if self.parent:
|
||||||
|
return self.parent.render(self.context)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def add_parent(self, nodelist):
|
||||||
|
if self.parent:
|
||||||
|
self.parent.add_parent(nodelist)
|
||||||
|
else:
|
||||||
|
self.parent = BlockNode(self.name, nodelist)
|
||||||
|
|
||||||
class ExtendsNode(template.Node):
|
class ExtendsNode(template.Node):
|
||||||
def __init__(self, nodelist, parent_name, parent_name_var, template_dirs=None):
|
def __init__(self, nodelist, parent_name, parent_name_var, template_dirs=None):
|
||||||
self.nodelist = nodelist
|
self.nodelist = nodelist
|
||||||
|
@ -104,8 +105,9 @@ class ExtendsNode(template.Node):
|
||||||
if parent_is_child:
|
if parent_is_child:
|
||||||
compiled_parent.nodelist[0].nodelist.append(block_node)
|
compiled_parent.nodelist[0].nodelist.append(block_node)
|
||||||
else:
|
else:
|
||||||
# Save the original nodelist. It's used by BlockNode.
|
# Keep any existing parents and add a new one. Used by BlockNode.
|
||||||
parent_block.original_node_list = parent_block.nodelist
|
parent_block.parent = block_node.parent
|
||||||
|
parent_block.add_parent(parent_block.nodelist)
|
||||||
parent_block.nodelist = block_node.nodelist
|
parent_block.nodelist = block_node.nodelist
|
||||||
return compiled_parent.render(context)
|
return compiled_parent.render(context)
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,18 @@ TEMPLATE_TESTS = {
|
||||||
# {% load %} tag (within a child template)
|
# {% load %} tag (within a child template)
|
||||||
'inheritance19': ("{% extends 'inheritance01' %}{% block first %}{% load testtags %}{% echo 400 %}5678{% endblock %}", {}, '140056783_'),
|
'inheritance19': ("{% extends 'inheritance01' %}{% block first %}{% load testtags %}{% echo 400 %}5678{% endblock %}", {}, '140056783_'),
|
||||||
|
|
||||||
|
# Two-level inheritance with {{ block.super }}
|
||||||
|
'inheritance20': ("{% extends 'inheritance01' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1_a3_'),
|
||||||
|
|
||||||
|
# Three-level inheritance with {{ block.super }} from parent
|
||||||
|
'inheritance21': ("{% extends 'inheritance02' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '12a34'),
|
||||||
|
|
||||||
|
# Three-level inheritance with {{ block.super }} from grandparent
|
||||||
|
'inheritance22': ("{% extends 'inheritance04' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1_a3_'),
|
||||||
|
|
||||||
|
# Three-level inheritance with {{ block.super }} from parent and grandparent
|
||||||
|
'inheritance23': ("{% extends 'inheritance20' %}{% block first %}{{ block.super }}b{% endblock %}", {}, '1_ab3_'),
|
||||||
|
|
||||||
### EXCEPTIONS ############################################################
|
### EXCEPTIONS ############################################################
|
||||||
|
|
||||||
# Raise exception for invalid template name
|
# Raise exception for invalid template name
|
||||||
|
|
Loading…
Reference in New Issue