mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 11:56:50 +00:00
bug #1361 Fixed recursively calling blocks in templates with inheritance (hason)
This PR was merged into the 1.15-dev branch. Discussion ---------- Fixed recursively calling blocks in templates with inheritance Replaces #1321 Fixes KnpLabs/KnpMenu#136 and KnpLabs/KnpMenu#119 Commits -------efb7b47Add "broken" block inheritance test caseef98ea2Fixed recursively calling blocks in templates with inheritance
This commit is contained in:
+15
-14
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,0 +1,32 @@
|
||||
--TEST--
|
||||
block_expr
|
||||
--TEMPLATE--
|
||||
{% extends "base.twig" %}
|
||||
|
||||
{% block element -%}
|
||||
Element:
|
||||
{{- parent() -}}
|
||||
{% endblock %}
|
||||
--TEMPLATE(base.twig)--
|
||||
{% spaceless %}
|
||||
{% block element -%}
|
||||
<div>
|
||||
{%- if item.children is defined %}
|
||||
{%- for item in item.children %}
|
||||
{{- block('element') -}}
|
||||
{% endfor %}
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
{% endspaceless %}
|
||||
--DATA--
|
||||
return array(
|
||||
'item' => array(
|
||||
'children' => array(
|
||||
null,
|
||||
null,
|
||||
)
|
||||
)
|
||||
)
|
||||
--EXPECT--
|
||||
Element:<div>Element:<div></div>Element:<div></div></div>
|
||||
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
block_expr2
|
||||
--TEMPLATE--
|
||||
{% extends "base2.twig" %}
|
||||
|
||||
{% block element -%}
|
||||
Element:
|
||||
{{- parent() -}}
|
||||
{% endblock %}
|
||||
--TEMPLATE(base2.twig)--
|
||||
{% extends "base.twig" %}
|
||||
--TEMPLATE(base.twig)--
|
||||
{% spaceless %}
|
||||
{% block element -%}
|
||||
<div>
|
||||
{%- if item.children is defined %}
|
||||
{%- for item in item.children %}
|
||||
{{- block('element') -}}
|
||||
{% endfor %}
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
{% endspaceless %}
|
||||
--DATA--
|
||||
return array(
|
||||
'item' => array(
|
||||
'children' => array(
|
||||
null,
|
||||
null,
|
||||
)
|
||||
)
|
||||
)
|
||||
--EXPECT--
|
||||
Element:<div>Element:<div></div>Element:<div></div></div>
|
||||
Reference in New Issue
Block a user