Open hlecorche opened 4 years ago
I'm having a similar issue, so I'm interested into why there is a difference between including the template, and rendering a block from a template.
Defining the template as such:
{# main.html.twig #}
{{ block('block1', 'theme.html.twig') }}
{% include 'theme.html.twig' %}
{# theme.html.twig #}
{% extends 'base.html.twig' %}
{%- block block1 -%}
{{- parent() -}}
BLOCK1THEME/
{%- endblock -%}
{%- block block2 -%}
BLOCK2THEME/
{%- endblock -%}
{# base.html.twig #}
{%- block block1 -%}
BLOCK1BASE/
{%- block block2 -%}
BLOCK2BASE/
{%- endblock -%}
{%- endblock -%}
https://twigfiddle.com/jae42d/3
I'd expect the outputs to be the same.
Looking at the compiled templates, including a block from another template displays the block from the parent.
It appears however that when rendering a block in a template with the block()
function, the inheritance is lost when displaying the block.
Is there a reason that the inheritance works differently when including a template vs rendering a specific block from a template?
edit:
When debugging the templates, I noticed that when including theme.html.twig
the parent is set, but when calling block('block1', 'theme.html.twig')
the parent is null
.
The parent is set in the doDisplay
call, when the extends
statement is evaluated. When displaying a block the doDisplay
is not called, and the parent is not loaded. It is not possible to call the extends
in a block, so it is not possible to set the parent inside a block, which I'm sure has a good reason to not allow.
I came across the same issue, I think that is one of the reasons why the symfony form component has it's own renderer.
I have a small workaround, the only limit is that you always have to passthrough the template name. I the way my usage is, I always know the template.
public function renderMenuBlock(Environment $environment, array $context, string $blockName, ?string $templateName = null): string
{
$templateName = $templateName ?? $this->defaultOptions['template'];
$template = $environment->resolveTemplate($templateName);
ob_start();
$template->displayBlock($blockName, $context);
return ob_get_clean();
}
Hello,
I found a strange behavior with all Twig versions.
https://twigfiddle.com/jae42d
The result is the expected result :
BLOCK1BASE/BLOCK2THEME/
But I have a strange result if block1 is overridden and
parent()
is called :https://twigfiddle.com/jae42d/2
Expected result :
BLOCK1BASE/BLOCK2THEME/BLOCK1THEME/
Result:BLOCK1BASE/BLOCK2BASE/BLOCK1THEME/