From ef98ea278a1e3b97ce0d89ae85cf82b17a14ba68 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20Haso=C5=88?= Date: Thu, 13 Mar 2014 12:23:25 +0100 Subject: [PATCH] Fixed recursively calling blocks in templates with inheritance --- lib/Twig/Template.php | 29 ++++++++++--------- .../recursive_block_with_inheritance.test | 21 ++++++++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test diff --git a/lib/Twig/Template.php b/lib/Twig/Template.php index b13df5d..1fe203f 100644 --- a/lib/Twig/Template.php +++ b/lib/Twig/Template.php @@ -105,9 +105,9 @@ abstract class Twig_Template implements Twig_TemplateInterface $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 @@ abstract class Twig_Template implements Twig_TemplateInterface * 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 @@ 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); } } 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 * 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(); } diff --git a/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test b/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test new file mode 100644 index 0000000..f39712d --- /dev/null +++ b/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test @@ -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') %}
    {{ block('children') }}
{% endblock %} +--TEMPLATE(menu.twig)-- +{% extends "base.twig" %} +{% block list %}{% endblock %} +{% block children %}{% set currentItem = item %}{% for item in currentItem %}{{ block('item') }}{% endfor %}{% set item = currentItem %}{% endblock %} +{% block item %}
  • {% if item is not iterable %}{{ block('label') }}{% else %}{{ block('list') }}{% endif %}
  • {% 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-- +
    1. "1"
    2. "2"
      1. "3.1"
        1. "3.2.1"
        2. "3.2.2"
      2. "3.4"
    -- 1.7.2.5