function HtmlRenderer::renderResponse

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php \Drupal\Core\Render\MainContent\HtmlRenderer::renderResponse()
  2. 8.9.x core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php \Drupal\Core\Render\MainContent\HtmlRenderer::renderResponse()
  3. 10 core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php \Drupal\Core\Render\MainContent\HtmlRenderer::renderResponse()

The entire HTML: takes a #type 'page' and wraps it in a #type 'html'.

Overrides MainContentRendererInterface::renderResponse

File

core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php, line 127

Class

HtmlRenderer
Default main content renderer for HTML requests.

Namespace

Drupal\Core\Render\MainContent

Code

public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) {
    [
        $page,
        $title,
    ] = $this->prepare($main_content, $request, $route_match);
    if (!isset($page['#type']) || $page['#type'] !== 'page') {
        throw new \LogicException('Must be #type page');
    }
    $page['#title'] = $title;
    // Now render the rendered page.html.twig template inside the html.html.twig
    // template, and use the bubbled #attached metadata from $page to ensure we
    // load all attached assets.
    $html = [
        '#type' => 'html',
        'page' => $page,
    ];
    // The special page regions will appear directly in html.html.twig, not in
    // page.html.twig, hence add them here, just before rendering html.html.twig.
    $this->buildPageTopAndBottom($html);
    // Render, but don't replace placeholders yet, because that happens later in
    // the render pipeline. To not replace placeholders yet, we use
    // RendererInterface::render() instead of RendererInterface::renderRoot().
    // @see \Drupal\Core\Render\HtmlResponseAttachmentsProcessor.
    $render_context = new RenderContext();
    $this->renderer
        ->executeInRenderContext($render_context, function () use (&$html) {
        // RendererInterface::render() renders the $html render array and updates
        // it in place. We don't care about the return value (which is just
        // $html['#markup']), but about the resulting render array.
        // @todo Simplify this when https://www.drupal.org/node/2495001 lands.
        $this->renderer
            ->render($html);
    });
    // RendererInterface::render() always causes bubbleable metadata to be
    // stored in the render context, no need to check it conditionally.
    $bubbleable_metadata = $render_context->pop();
    $bubbleable_metadata->applyTo($html);
    $content = $this->renderCache
        ->getCacheableRenderArray($html);
    // Also associate the required cache contexts.
    // (Because we use ::render() above and not ::renderRoot(), we manually must
    // ensure the HTML response varies by the required cache contexts.)
    $content['#cache']['contexts'] = Cache::mergeContexts($content['#cache']['contexts'], $this->rendererConfig['required_cache_contexts']);
    // Also associate the "rendered" cache tag. This allows us to invalidate the
    // entire render cache, regardless of the cache bin.
    $content['#cache']['tags'][] = 'rendered';
    $response = new HtmlResponse($content, 200, [
        'Content-Type' => 'text/html; charset=UTF-8',
    ]);
    return $response;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.