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:
Adrian Holovaty 2005-09-29 04:22:09 +00:00
parent 26021249a4
commit 8a7189f38f
2 changed files with 31 additions and 17 deletions

View File

@ -42,32 +42,33 @@ def select_template(template_name_list):
# If we get here, none of the templates could be loaded
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):
def __init__(self, name, nodelist):
self.name, self.nodelist = name, nodelist
def __init__(self, name, nodelist, parent=None):
self.name, self.nodelist, self.parent = name, nodelist, parent
def __repr__(self):
return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist)
def render(self, context):
context.push()
nodelist = hasattr(self, 'original_node_list') and self.original_node_list or None
context['block'] = SuperBlock(context, nodelist)
# Save context in case of block.super().
self.context = context
context['block'] = self
result = self.nodelist.render(context)
context.pop()
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):
def __init__(self, nodelist, parent_name, parent_name_var, template_dirs=None):
self.nodelist = nodelist
@ -104,8 +105,9 @@ class ExtendsNode(template.Node):
if parent_is_child:
compiled_parent.nodelist[0].nodelist.append(block_node)
else:
# Save the original nodelist. It's used by BlockNode.
parent_block.original_node_list = parent_block.nodelist
# Keep any existing parents and add a new one. Used by BlockNode.
parent_block.parent = block_node.parent
parent_block.add_parent(parent_block.nodelist)
parent_block.nodelist = block_node.nodelist
return compiled_parent.render(context)

View File

@ -185,6 +185,18 @@ TEMPLATE_TESTS = {
# {% load %} tag (within a child template)
'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 ############################################################
# Raise exception for invalid template name