Skip to content

Commit

Permalink
bug #2269 Bugfix: When rendering blocks of other templates, don't pas…
Browse files Browse the repository at this point in the history
…s the local blocks array (derrabus, fabpot)

This PR was merged into the 1.x branch.

Discussion
----------

Bugfix: When rendering blocks of other templates, don't pass the local blocks array

This PR fixes symfony/symfony#20556.

When referring to a block of another template from within a template that also has a block with the same name, Twig renders the wrong block.

Commits
-------

8c090a7 added tests for block() when using a template argument
a5526f3 fixed block() is defined call when using a template argument
c04d077 Bugfix: When rendering blocks of other templates, don't pass the local blocks array.
  • Loading branch information
fabpot committed Nov 19, 2016
2 parents a1eb0f5 + 8c090a7 commit f59b33a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 28 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
* 1.28.1 (2016-XX-XX)

* n/a
* fixed block() function when used with a template argument

* 1.28.0 (2016-11-17)

Expand Down
61 changes: 34 additions & 27 deletions lib/Twig/Node/Expression/BlockReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,46 +39,53 @@ public function __construct(Twig_NodeInterface $name, $template = null, $lineno,
public function compile(Twig_Compiler $compiler)
{
if ($this->getAttribute('is_defined_test')) {
$compiler
->raw('$this->hasBlock(')
->subcompile($this->getNode('name'))
->raw(', $context, $blocks)')
;
$this->compileTemplateCall($compiler, 'hasBlock');
} else {
if ($this->getAttribute('output')) {
$compiler->addDebugInfo($this);

$this
->compileTemplateCall($compiler)
->raw('->displayBlock(')
->subcompile($this->getNode('name'))
->raw(", \$context, \$blocks);\n")
;
->compileTemplateCall($compiler, 'displayBlock')
->raw(";\n");
} else {
$this
->compileTemplateCall($compiler)
->raw('->renderBlock(')
->subcompile($this->getNode('name'))
->raw(', $context, $blocks)')
;
$this->compileTemplateCall($compiler, 'renderBlock');
}
}
}

private function compileTemplateCall(Twig_Compiler $compiler)
private function compileTemplateCall(Twig_Compiler $compiler, $method)
{
if (!$this->hasNode('template')) {
$compiler->write('$this');
} else {
$compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('template'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}

$compiler->raw(sprintf('->%s', $method));
$this->compileBlockArguments($compiler);

return $compiler;
}

private function compileBlockArguments(Twig_Compiler $compiler)
{
$compiler
->raw('(')
->subcompile($this->getNode('name'))
->raw(', $context');

if (!$this->hasNode('template')) {
return $compiler->write('$this');
$compiler->raw(', $blocks');
}

return $compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('template'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
return $compiler->raw(')');
}
}
22 changes: 22 additions & 0 deletions test/Twig/Tests/Fixtures/functions/block_with_template.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
"block" function with a template argument
--TEMPLATE--
{{ block('foo', 'included.twig') }}
{{ block('foo', included_loaded) }}
{{ block('foo', included_loaded_internal) }}
{% set output = block('foo', 'included.twig') %}
{{ output }}
{% block foo %}NOT FOO{% endblock %}
--TEMPLATE(included.twig)--
{% block foo %}FOO{% endblock %}
--DATA--
return array(
'included_loaded' => $twig->load('included.twig'),
'included_loaded_internal' => $twig->loadTemplate('included.twig'),
)
--EXPECT--
FOO
FOO
FOO
FOO
NOT FOO
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
"defined" support for blocks with a template argument
--TEMPLATE--
{{ block('foo', 'included.twig') is defined ? 'ok' : 'ko' }}
{{ block('foo', included_loaded) is defined ? 'ok' : 'ko' }}
{{ block('foo', included_loaded_internal) is defined ? 'ok' : 'ko' }}
--TEMPLATE(included.twig)--
{% block foo %}FOO{% endblock %}
--DATA--
return array(
'included_loaded' => $twig->load('included.twig'),
'included_loaded_internal' => $twig->loadTemplate('included.twig'),
)
--EXPECT--
ok
ok
ok

0 comments on commit f59b33a

Please sign in to comment.