Fixed recursively calling blocks in templates with inheritance

This commit is contained in:
Martin Hasoň
2014-03-13 12:23:25 +01:00
parent 5fd4db64de
commit ef98ea278a
2 changed files with 36 additions and 14 deletions
+15 -14
View File
@@ -105,9 +105,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
$name = (string) $name; $name = (string) $name;
if (isset($this->traits[$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)) { } elseif (false !== $parent = $this->getParent($context)) {
$parent->displayBlock($name, $context, $blocks); $parent->displayBlock($name, $context, $blocks, false);
} else { } else {
throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName()); 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 @@ abstract class Twig_Template implements Twig_TemplateInterface
* This method is for internal use only and should never be called * This method is for internal use only and should never be called
* directly. * directly.
* *
* @param string $name The block name to display * @param string $name The block name to display
* @param array $context The context * @param array $context The context
* @param array $blocks The current set of blocks * @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; $name = (string) $name;
if (isset($blocks[$name])) { if ($useBlocks && isset($blocks[$name])) {
$template = $blocks[$name][0]; $template = $blocks[$name][0];
$block = $blocks[$name][1]; $block = $blocks[$name][1];
unset($blocks[$name]);
} elseif (isset($this->blocks[$name])) { } elseif (isset($this->blocks[$name])) {
$template = $this->blocks[$name][0]; $template = $this->blocks[$name][0];
$block = $this->blocks[$name][1]; $block = $this->blocks[$name][1];
@@ -148,7 +148,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e); 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)) { } 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 @@ abstract class Twig_Template implements Twig_TemplateInterface
* This method is for internal use only and should never be called * This method is for internal use only and should never be called
* directly. * directly.
* *
* @param string $name The block name to render * @param string $name The block name to render
* @param array $context The context * @param array $context The context
* @param array $blocks The current set of blocks * @param array $blocks The current set of blocks
* @param Boolean $useBlocks Whether to use the current set of blocks
* *
* @return string The rendered block * @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(); ob_start();
$this->displayBlock($name, $context, $blocks); $this->displayBlock($name, $context, $blocks, $useBlocks);
return ob_get_clean(); 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>