Permalink
Browse files

Fixed recursively calling blocks in templates with inheritance

  • Loading branch information...
1 parent 5fd4db6 commit ef98ea278a1e3b97ce0d89ae85cf82b17a14ba68 @hason hason committed Mar 13, 2014
Showing with 36 additions and 14 deletions.
  1. +15 −14 lib/Twig/Template.php
  2. +21 −0 test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test
View
@@ -105,9 +105,9 @@ public function displayParentBlock($name, array $context, array $blocks = array(
$name = (string) $name;
if (isset($this->traits[$name])) {
- $this->traits[$name][0]->displayBlock($name, $context, $blocks);
+ $this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
} elseif (false !== $parent = $this->getParent($context)) {
- $parent->displayBlock($name, $context, $blocks);
+ $parent->displayBlock($name, $context, $blocks, false);
} else {
throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
}
@@ -119,18 +119,18 @@ public function displayParentBlock($name, array $context, array $blocks = array(
* This method is for internal use only and should never be called
* directly.
*
- * @param string $name The block name to display
- * @param array $context The context
- * @param array $blocks The current set of blocks
+ * @param string $name The block name to display
+ * @param array $context The context
+ * @param array $blocks The current set of blocks
+ * @param Boolean $useBlocks Whether to use the current set of blocks
*/
- public function displayBlock($name, array $context, array $blocks = array())
+ public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
{
$name = (string) $name;
- if (isset($blocks[$name])) {
+ if ($useBlocks && isset($blocks[$name])) {
$template = $blocks[$name][0];
$block = $blocks[$name][1];
- unset($blocks[$name]);
} elseif (isset($this->blocks[$name])) {
$template = $this->blocks[$name][0];
$block = $this->blocks[$name][1];
@@ -148,7 +148,7 @@ public function displayBlock($name, array $context, array $blocks = array())
throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e);
}
} elseif (false !== $parent = $this->getParent($context)) {
- $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks));
+ $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
}
}
@@ -178,16 +178,17 @@ public function renderParentBlock($name, array $context, array $blocks = array()
* This method is for internal use only and should never be called
* directly.
*
- * @param string $name The block name to render
- * @param array $context The context
- * @param array $blocks The current set of blocks
+ * @param string $name The block name to render
+ * @param array $context The context
+ * @param array $blocks The current set of blocks
+ * @param Boolean $useBlocks Whether to use the current set of blocks
*
* @return string The rendered block
*/
- public function renderBlock($name, array $context, array $blocks = array())
+ public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
{
ob_start();
- $this->displayBlock($name, $context, $blocks);
+ $this->displayBlock($name, $context, $blocks, $useBlocks);
return ob_get_clean();
}
@@ -0,0 +1,21 @@
+--TEST--
+"block" function recursively called in a parent template
+--TEMPLATE--
+{% extends "ordered_menu.twig" %}
+{% block label %}"{{ parent() }}"{% endblock %}
+{% block list %}{% set class = 'b' %}{{ parent() }}{% endblock %}
+--TEMPLATE(ordered_menu.twig)--
+{% extends "menu.twig" %}
+{% block list %}{% set class = class|default('a') %}<ol class="{{ class }}">{{ block('children') }}</ol>{% endblock %}
+--TEMPLATE(menu.twig)--
+{% extends "base.twig" %}
+{% block list %}<ul>{{ block('children') }}</ul>{% endblock %}
+{% block children %}{% set currentItem = item %}{% for item in currentItem %}{{ block('item') }}{% endfor %}{% set item = currentItem %}{% endblock %}
+{% block item %}<li>{% if item is not iterable %}{{ block('label') }}{% else %}{{ block('list') }}{% endif %}</li>{% endblock %}
+{% block label %}{{ item }}{{ block('unknown') }}{% endblock %}
+--TEMPLATE(base.twig)--
+{{ block('list') }}
+--DATA--
+return array('item' => array('1', '2', array('3.1', array('3.2.1', '3.2.2'), '3.4')))
+--EXPECT--
+<ol class="b"><li>"1"</li><li>"2"</li><li><ol class="b"><li>"3.1"</li><li><ol class="b"><li>"3.2.1"</li><li>"3.2.2"</li></ol></li><li>"3.4"</li></ol></li></ol>

0 comments on commit ef98ea2

Please sign in to comment.