Problem/Motivation
Within a templateregion--header.html.twig
we render a block "manually" by calling " a custom block via {{ elements.my_project_block_plugin_1 }}
. This leads to a fatal error in case the custom block plugin returns an empty markup string
public function build() {
// [...]
return [
'#markup' => '',
];
}
:
Error: Call to a member function getPlugin() on null in Drupal\block\BlockViewBuilder::preRender() (line 203 of core/modules/block/src/BlockViewBuilder.php).
It appears that some circumstances lead to the block being rendered a second time, although it has been rendered before and has been marked as #printed
already:
- Region "header" is rendered in
page.html.twig
as{{ page.header }}
. - This leads to all children being render processed and concatenated to
#children
beforehand. - As the region template itself renders the child directly via
{{ elements.my_project_block_plugin_1 }}
, the block is passed to\Drupal\Core\Template\TwigExtension::escapeFilter()
once again. - There the check on the element being already renders fails, as it also checks on
strlen($arg['#markup']) > 0
. - This leads to the re-rendering of the block - at least the try of it.
From my perspective this seems like a generic bug, as this may lead to multiple render processing of elements that simply will fall back to an empty string.
Proposed resolution
* Remove the general check on strlen($arg['#markup'])
in
// Early return if this element was pre-rendered (no need to re-render).
if (isset($arg['#printed']) && $arg['#printed'] == TRUE && isset($arg['#markup']) && strlen($arg['#markup']) > 0) {
return $arg['#markup'];
}
appearing in \Drupal\Core\Template\TwigExtension::escapeFilter()
and \Drupal\Core\Template\TwigExtension::renderVar()
Remaining tasks
* Write a test.
* Clarify what the intensions were in #2464045: Move twig_render_var/twig_drupal_escape_filter to TwigExtension, inject the renderer in Twig extension and inline render() / show() function instead of calling it of adding strlen($arg['#markup'])
.
* Fix
User interface changes
-
API changes
-
Data model changes
-
Comments
Comment #7
acbramley CreditAttribution: acbramley at PreviousNext for Service NSW commentedJust on 6 years with no futher comments, is this still an issue?
The strlen check still exists in 11.x, and the description in the IS is a bit confusing, specifically:
But the code comments state the opposite - i.e it's trying to prevent re-rendering.
If the problem still exists, please provide steps to reproduce from a fresh installation of Drupal core.
Thanks!