public function BlockFieldFormatter::preRender in Block field 8
The #pre_render callback for building a block.
Renders the content using the provided block plugin, and then:
- if there is no content, aborts rendering, and makes sure the block won't be rendered.
- if there is content, moves the contextual links from the block content to the block itself.
See also
\Drupal\block\BlockViewBuilder::preRender
File
- src/
Plugin/ Field/ FieldFormatter/ BlockFieldFormatter.php, line 191
Class
- BlockFieldFormatter
- Plugin implementation of the 'block_field' formatter.
Namespace
Drupal\block_field\Plugin\Field\FieldFormatterCode
public function preRender($build) {
$content = $build['#block']
->build();
// Remove the block entity from the render array, to ensure that blocks
// can be rendered without the block config entity.
unset($build['#block']);
if ($content !== NULL && !Element::isEmpty($content)) {
// Place the $content returned by the block plugin into a 'content' child
// element, as a way to allow the plugin to have complete control of its
// properties and rendering (for instance, its own #theme) without
// conflicting with the properties used above, or alternate ones used by
// alternate block rendering approaches in contrib (for instance, Panels).
// However, the use of a child element is an implementation detail of this
// particular block rendering approach. Semantically, the content returned
// by the plugin "is the" block, and in particular, #attributes and
// #contextual_links is information about the *entire* block. Therefore,
// we must move these properties from $content and merge them into the
// top-level element.
foreach ([
'#attributes',
'#contextual_links',
] as $property) {
if (isset($content[$property])) {
if (empty($build[$property])) {
$build[$property] = [];
}
$build[$property] += $content[$property];
unset($content[$property]);
}
}
$build['content'] = $content;
}
else {
// Abort rendering: render as the empty string and ensure this block is
// render cached, so we can avoid the work of having to repeatedly
// determine whether the block is empty. For instance, modifying or adding
// entities could cause the block to no longer be empty.
$build = [
'#markup' => '',
'#cache' => $build['#cache'],
];
}
// If $content is not empty, then it contains cacheability metadata, and
// we must merge it with the existing cacheability metadata. This allows
// blocks to be empty, yet still bubble cacheability metadata, to indicate
// why they are empty.
if (!empty($content)) {
CacheableMetadata::createFromRenderArray($build)
->merge(CacheableMetadata::createFromRenderArray($content))
->applyTo($build);
}
return $build;
}