You are here

public function BlockViewBuilder::build in Twig Tweak 3.x

Same name and namespace in other branches
  1. 3.1.x src/View/BlockViewBuilder.php \Drupal\twig_tweak\View\BlockViewBuilder::build()

Builds the render array for a block.

Parameters

string $id: The string of block plugin to render.

array $configuration: (optional) Pass on any configuration to the plugin block.

bool $wrapper: (optional) Whether or not use block template for rendering.

Return value

array A renderable array representing the content of the block.

File

src/View/BlockViewBuilder.php, line 106

Class

BlockViewBuilder
Block view builder.

Namespace

Drupal\twig_tweak\View

Code

public function build(string $id, array $configuration = [], bool $wrapper = TRUE) : array {
  $configuration += [
    'label_display' => BlockPluginInterface::BLOCK_LABEL_VISIBLE,
  ];

  /** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */
  $block_plugin = $this->pluginManagerBlock
    ->createInstance($id, $configuration);

  // Inject runtime contexts.
  if ($block_plugin instanceof ContextAwarePluginInterface) {
    $contexts = $this->contextRepository
      ->getRuntimeContexts($block_plugin
      ->getContextMapping());
    $this->contextHandler
      ->applyContextMapping($block_plugin, $contexts);
  }
  $build = [];
  $access = $block_plugin
    ->access($this->account, TRUE);
  if ($access
    ->isAllowed()) {

    // Title block needs a special treatment.
    if ($block_plugin instanceof TitleBlockPluginInterface) {
      $request = $this->requestStack
        ->getCurrentRequest();
      $title = $this->titleResolver
        ->getTitle($request, $this->routeMatch
        ->getRouteObject());
      $block_plugin
        ->setTitle($title);
    }

    // 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.
    $build['content'] = $block_plugin
      ->build();
    if ($block_plugin instanceof TitleBlockPluginInterface) {
      $build['content']['#cache']['contexts'][] = 'url';
    }

    // Some blocks return null instead of array when empty.
    // @see https://www.drupal.org/project/drupal/issues/3212354
    if ($wrapper && is_array($build['content']) && !Element::isEmpty($build['content'])) {
      $build += [
        '#theme' => 'block',
        '#id' => $configuration['id'] ?? NULL,
        '#attributes' => [],
        '#contextual_links' => [],
        '#configuration' => $block_plugin
          ->getConfiguration(),
        '#plugin_id' => $block_plugin
          ->getPluginId(),
        '#base_plugin_id' => $block_plugin
          ->getBaseId(),
        '#derivative_plugin_id' => $block_plugin
          ->getDerivativeId(),
      ];

      // 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 into the
      // top-level element.
      foreach ([
        '#attributes',
        '#contextual_links',
      ] as $property) {
        if (isset($build['content'][$property])) {
          $build[$property] = $build['content'][$property];
          unset($build['content'][$property]);
        }
      }
    }
  }
  CacheableMetadata::createFromRenderArray($build)
    ->merge(CacheableMetadata::createFromObject($access))
    ->merge(CacheableMetadata::createFromObject($block_plugin))
    ->applyTo($build);
  if (!isset($build['#cache']['keys'])) {
    $build['#cache']['keys'] = [
      'twig_tweak_block',
      $id,
      '[configuration]=' . hash('sha256', serialize($configuration)),
      '[wrapper]=' . (int) $wrapper,
    ];
  }
  return $build;
}