From 8a7189f38f08c515e7302a484d7af0c215e92973 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Thu, 29 Sep 2005 04:22:09 +0000 Subject: [PATCH] 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 --- django/core/template_loader.py | 36 ++++++++++++++++++---------------- tests/othertests/templates.py | 12 ++++++++++++ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/django/core/template_loader.py b/django/core/template_loader.py index c2b41f3743..1d973df687 100644 --- a/django/core/template_loader.py +++ b/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 "" % (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) diff --git a/tests/othertests/templates.py b/tests/othertests/templates.py index 07b41f5b10..31fea0e1ba 100644 --- a/tests/othertests/templates.py +++ b/tests/othertests/templates.py @@ -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