function Renderer::replacePlaceholders
Same name in other branches
- 9 core/lib/Drupal/Core/Render/Renderer.php \Drupal\Core\Render\Renderer::replacePlaceholders()
- 8.9.x core/lib/Drupal/Core/Render/Renderer.php \Drupal\Core\Render\Renderer::replacePlaceholders()
- 11.x 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.
Parameters
array &$elements: The structured array describing the data being rendered. Including the bubbleable metadata associated with the markup that replaced the placeholders.
Return value
bool Whether placeholders were replaced.
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 695
Class
- Renderer
- Turns a render array into an HTML string.
Namespace
Drupal\Core\RenderCode
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 = [];
$fibers = [];
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 {
// Get the render array for the given placeholder
$fibers[$placeholder] = new \Fiber(function () use ($placeholder_element) {
return [
$this->doRenderPlaceholder($placeholder_element),
$placeholder_element,
];
});
}
}
$iterations = 0;
while (count($fibers) > 0) {
foreach ($fibers as $placeholder => $fiber) {
if (!$fiber->isStarted()) {
$fiber->start();
}
elseif ($fiber->isSuspended()) {
$fiber->resume();
}
// If the Fiber hasn't terminated by this point, move onto the next
// placeholder, we'll resume this fiber again when we get back here.
if (!$fiber->isTerminated()) {
// If we've gone through the placeholders once already, and they're
// still not finished, then start to allow code higher up the stack to
// get on with something else.
if ($iterations) {
$fiber = \Fiber::getCurrent();
if ($fiber !== NULL) {
$fiber->suspend();
}
}
continue;
}
[
$markup,
$placeholder_element,
] = $fiber->getReturn();
$elements = $this->doReplacePlaceholder($placeholder, $markup, $elements, $placeholder_element);
unset($fibers[$placeholder]);
}
$iterations++;
}
// Then render 'status messages' placeholders.
foreach ($message_placeholders as $message_placeholder) {
$elements = $this->renderPlaceholder($message_placeholder, $elements);
}
return TRUE;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.