You are here

public static function BlockViewBuilder::preRender in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/block/src/BlockViewBuilder.php \Drupal\block\BlockViewBuilder::preRender()

#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.

File

core/modules/block/src/BlockViewBuilder.php, line 206
Contains \Drupal\block\BlockViewBuilder.

Class

BlockViewBuilder
Provides a Block view builder.

Namespace

Drupal\block

Code

public static function preRender($build) {
  $content = $build['#block']
    ->getPlugin()
    ->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 (e.g., its own #theme) without conflicting
    // with the properties used above, or alternate ones used by alternate
    // block rendering approaches in contrib (e.g., 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 (array(
      '#attributes',
      '#contextual_links',
    ) as $property) {
      if (isset($content[$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. E.g. modifying or adding entities
    // could cause the block to no longer be empty.
    $build = array(
      '#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;
}