From 279fe13b224353fcfe3f1855d2d411eff38ec448 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 3 Jun 2026 22:09:09 +0200 Subject: [PATCH] Fix nested block() resolution when a directly rendered block calls parent() --- CHANGELOG | 1 + src/Template.php | 2 ++ .../functions/block_with_template_parent.test | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 tests/Fixtures/functions/block_with_template_parent.test diff --git a/CHANGELOG b/CHANGELOG index 1d347b542..a266a8a49 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ # 3.27.2 (2026-XX-XX) + * Fix nested `block()` calls to resolve against the overriding template when a block rendered through `block(name, template)` calls `parent()` * Stop reporting a skipped test in `IntegrationTestCase` when there is no legacy test to run * Make the `IntegrationTestCase` and `NodeTestCase` test helpers compatible with PHPUnit 11 * Cast printed expressions to string so values that cannot be converted to a string (arrays, non-`Stringable` objects, ...) report a usable stack trace at the print location diff --git a/src/Template.php b/src/Template.php index e32c85d0f..3d74460b0 100644 --- a/src/Template.php +++ b/src/Template.php @@ -440,6 +440,8 @@ abstract class Template } elseif (isset($this->blocks[$name])) { $template = $this->blocks[$name][0]; $block = $this->blocks[$name][1]; + // expose this template's own blocks so nested block() calls resolve against them when the block is rendered directly (e.g. block(name, template)) + $blocks = array_merge($this->blocks, $blocks); } else { $template = null; $block = null; diff --git a/tests/Fixtures/functions/block_with_template_parent.test b/tests/Fixtures/functions/block_with_template_parent.test new file mode 100644 index 000000000..17a2698ea --- /dev/null +++ b/tests/Fixtures/functions/block_with_template_parent.test @@ -0,0 +1,28 @@ +--TEST-- +"block" function with a template argument resolves nested "block" calls against the overriding template through parent() +--TEMPLATE-- +{{ block('block1', 'theme.html.twig') }} +--TEMPLATE(theme.html.twig)-- +{% extends 'base.html.twig' %} + +{%- block block1 -%} + {{- parent() -}} + BLOCK1THEME/ +{%- endblock -%} + +{%- block block2 -%} + BLOCK2THEME/ +{%- endblock -%} +--TEMPLATE(base.html.twig)-- +{%- block block1 -%} + BLOCK1BASE/ + {{- block('block2') -}} +{%- endblock -%} + +{%- block block2 -%} + BLOCK2BASE/ +{%- endblock -%} +--DATA-- +return [] +--EXPECT-- +BLOCK1BASE/BLOCK2THEME/BLOCK1THEME/