You are here

protected function Renderer::replacePlaceholders in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Render/Renderer.php \Drupal\Core\Render\Renderer::replacePlaceholders()
  2. 10 core/lib/Drupal/Core/Render/Renderer.php \Drupal\Core\Render\Renderer::replacePlaceholders()

Replaces placeholders.

Placeholders may have:

  • #lazy_builder callback, to build a render array to be rendered into markup that can replace the placeholder
  • #cache: to cache the result of the placeholder

Also merges the bubbleable metadata resulting from the rendering of the contents of the placeholders. Hence $elements will be contain the entirety of bubbleable metadata.

@returns bool Whether placeholders were replaced.

Parameters

array &$elements: The structured array describing the data being rendered. Including the bubbleable metadata associated with the markup that replaced the placeholders.

See also

\Drupal\Core\Render\Renderer::renderPlaceholder()

1 call to Renderer::replacePlaceholders()
Renderer::doRender in core/lib/Drupal/Core/Render/Renderer.php
See the docs for ::render().

File

core/lib/Drupal/Core/Render/Renderer.php, line 633

Class

Renderer
Turns a render array into a HTML string.

Namespace

Drupal\Core\Render

Code

protected function replacePlaceholders(array &$elements) {
  if (!isset($elements['#attached']['placeholders']) || empty($elements['#attached']['placeholders'])) {
    return FALSE;
  }

  // The 'status messages' placeholder needs to be special cased, because it
  // depends on global state that can be modified when other placeholders are
  // being rendered: any code can add messages to render.
  // This violates the principle that each lazy builder must be able to render
  // itself in isolation, and therefore in any order. However, we cannot
  // change the way \Drupal\Core\Messenger\Messenger works in the Drupal 8
  // cycle. So we have to accommodate its special needs.
  // Allowing placeholders to be rendered in a particular order (in this case:
  // last) would violate this isolation principle. Thus a monopoly is granted
  // to this one special case, with this hard-coded solution.
  // @see \Drupal\Core\Render\Element\StatusMessages
  // @see https://www.drupal.org/node/2712935#comment-11368923
  // First render all placeholders except 'status messages' placeholders.
  $message_placeholders = [];
  foreach ($elements['#attached']['placeholders'] as $placeholder => $placeholder_element) {
    if (isset($placeholder_element['#lazy_builder']) && $placeholder_element['#lazy_builder'][0] === 'Drupal\\Core\\Render\\Element\\StatusMessages::renderMessages') {
      $message_placeholders[] = $placeholder;
    }
    else {
      $elements = $this
        ->renderPlaceholder($placeholder, $elements);
    }
  }

  // Then render 'status messages' placeholders.
  foreach ($message_placeholders as $message_placeholder) {
    $elements = $this
      ->renderPlaceholder($message_placeholder, $elements);
  }
  return TRUE;
}