Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #501 -- Fixed block.super in multi-level templates, and added u…

…nit 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
  • Loading branch information...
commit 8a7189f38f08c515e7302a484d7af0c215e92973 1 parent 2602124
@adrianholovaty adrianholovaty authored
Showing with 31 additions and 17 deletions.
  1. +19 −17 django/core/template_loader.py
  2. +12 −0 tests/othertests/templates.py
View
36 django/core/template_loader.py
@@ -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 @@ def render(self, context):
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
12 tests/othertests/templates.py
@@ -185,6 +185,18 @@ def method(self):
# {% 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
Please sign in to comment.
Something went wrong with that request. Please try again.