function HtmlRenderer::prepare
Same name in other branches
- 9 core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php \Drupal\Core\Render\MainContent\HtmlRenderer::prepare()
- 8.9.x core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php \Drupal\Core\Render\MainContent\HtmlRenderer::prepare()
- 10 core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php \Drupal\Core\Render\MainContent\HtmlRenderer::prepare()
Prepares the HTML body: wraps the main content in #type 'page'.
Parameters
array $main_content: The render array representing the main content.
\Symfony\Component\HttpFoundation\Request $request: The request object, for context.
\Drupal\Core\Routing\RouteMatchInterface $route_match: The route match, for context.
Return value
array An array with two values: 0. A #type 'page' render array. 1. The page title.
Throws
\LogicException If the selected display variant does not implement PageVariantInterface.
1 call to HtmlRenderer::prepare()
- HtmlRenderer::renderResponse in core/
lib/ Drupal/ Core/ Render/ MainContent/ HtmlRenderer.php - The entire HTML: takes a #type 'page' and wraps it in a #type 'html'.
File
-
core/
lib/ Drupal/ Core/ Render/ MainContent/ HtmlRenderer.php, line 200
Class
- HtmlRenderer
- Default main content renderer for HTML requests.
Namespace
Drupal\Core\Render\MainContentCode
protected function prepare(array $main_content, Request $request, RouteMatchInterface $route_match) {
// Determine the title: use the title provided by the main content if any,
// otherwise get it from the routing information.
$get_title = function (array $main_content) use ($request, $route_match) {
return $main_content['#title'] ?? $this->titleResolver
->getTitle($request, $route_match->getRouteObject());
};
// If the _controller result already is #type => page,
// we have no work to do: The "main content" already is an entire "page"
// (see html.html.twig).
if (isset($main_content['#type']) && $main_content['#type'] === 'page') {
$page = $main_content;
$title = $get_title($page);
}
else {
// Select the page display variant to be used to render this main content,
// default to the built-in "simple page".
$event = new PageDisplayVariantSelectionEvent('simple_page', $route_match);
$this->eventDispatcher
->dispatch($event, RenderEvents::SELECT_PAGE_DISPLAY_VARIANT);
$variant_id = $event->getPluginId();
$variant_configuration = $event->getPluginConfiguration();
// We must render the main content now already, because it might provide a
// title. We set its $is_root_call parameter to FALSE, to ensure
// placeholders are not yet replaced. This is essentially "pre-rendering"
// the main content, the "full rendering" will happen in
// ::renderResponse().
// @todo Remove this once https://www.drupal.org/node/2359901 lands.
if (!empty($main_content)) {
$this->renderer
->executeInRenderContext(new RenderContext(), function () use (&$main_content) {
if (isset($main_content['#cache']['keys'])) {
// Retain #title, otherwise, dynamically generated titles would be
// missing for controllers whose entire returned render array is
// render cached.
$main_content['#cache_properties'][] = '#title';
}
return $this->renderer
->render($main_content, FALSE);
});
$main_content = $this->renderCache
->getCacheableRenderArray($main_content) + [
'#title' => $main_content['#title'] ?? NULL,
];
}
$title = $get_title($main_content);
// Instantiate the page display, and give it the main content.
$page_display = $this->displayVariantManager
->createInstance($variant_id, $variant_configuration);
if (!$page_display instanceof PageVariantInterface) {
throw new \LogicException('Cannot render the main content for this page because the provided display variant does not implement PageVariantInterface.');
}
$page_display->setMainContent($main_content)
->setTitle($title)
->addCacheableDependency($event);
// Some display variants need to be passed an array of contexts with
// values because they can't get all their contexts globally. For example,
// in Page Manager, you can create a Page which has a specific static
// context (e.g. a context that refers to the Node with nid 6), if any
// such contexts were added to the $event, pass them to the $page_display.
if ($page_display instanceof ContextAwareVariantInterface) {
$page_display->setContexts($event->getContexts());
}
// Generate a #type => page render array using the page display variant,
// the page display will build the content for the various page regions.
$page = [
'#type' => 'page',
];
$page += $page_display->build();
}
// $page is now fully built. Find all non-empty page regions, and add a
// theme wrapper function that allows them to be consistently themed.
$regions = $this->themeManager
->getActiveTheme()
->getRegions();
foreach ($regions as $region) {
if (!empty($page[$region])) {
$page[$region]['#theme_wrappers'][] = 'region';
$page[$region]['#region'] = $region;
}
}
// Allow hooks to add attachments to $page['#attached'].
$this->renderer
->executeInRenderContext(new RenderContext(), function () use (&$page) {
$this->invokePageAttachmentHooks($page);
});
return [
$page,
$title,
];
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.