Commit e6681d4e authored by catch's avatar catch

Issue #2256365 by Crell, Wim Leers, dawehner: Factor render->fragment code out to a service.

parent e1081c61
......@@ -643,7 +643,7 @@ services:
- { name: event_subscriber }
controller.page:
class: Drupal\Core\Controller\HtmlPageController
arguments: ['@controller_resolver', '@title_resolver', '@url_generator']
arguments: ['@controller_resolver', '@title_resolver', '@render_html_renderer']
controller.ajax:
class: Drupal\Core\Controller\AjaxController
arguments: ['@controller_resolver', '@ajax_response_renderer']
......@@ -669,6 +669,9 @@ services:
tags:
- { name: event_subscriber }
arguments: ['@html_fragment_renderer', '@html_page_renderer']
render_html_renderer:
class: Drupal\Core\Page\RenderHtmlRenderer
arguments: ['@url_generator']
html_fragment_renderer:
class: Drupal\Core\Page\DefaultHtmlFragmentRenderer
arguments: ['@language_manager']
......
......@@ -7,9 +7,8 @@
namespace Drupal\Core\Controller;
use Drupal\Core\Page\FeedLinkElement;
use Drupal\Core\Page\HtmlFragment;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Page\RenderHtmlRendererInterface;
use Drupal\Core\Utility\Title;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
......@@ -23,28 +22,28 @@ class HtmlControllerBase {
/**
* The title resolver.
*
* @var \Drupal\Core\Controller\TitleResolver
* @var \Drupal\Core\Controller\TitleResolverInterface
*/
protected $titleResolver;
/**
* The url generator.
* The render array to HTML fragment renderer.
*
* @var \Drupal\Core\Routing\UrlGeneratorInterface
* @var \Drupal\Core\Page\RenderHtmlRendererInterface
*/
protected $urlGenerator;
protected $renderHtmlRenderer;
/**
* Constructs a new HtmlControllerBase object.
*
* @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
* The title resolver.
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The url generator.
* @param \Drupal\Core\Page\RenderHtmlRendererInterface $render_html_renderer
* The render array to HTML fragment renderer.
*/
public function __construct(TitleResolverInterface $title_resolver, UrlGeneratorInterface $url_generator) {
public function __construct(TitleResolverInterface $title_resolver, RenderHtmlRendererInterface $render_html_renderer) {
$this->titleResolver = $title_resolver;
$this->urlGenerator = $url_generator;
$this->renderHtmlRenderer = $render_html_renderer;
}
/**
......@@ -65,47 +64,16 @@ protected function createHtmlFragment($page_content, Request $request) {
}
if (!is_array($page_content)) {
$page_content = array(
'main' => array(
'#markup' => $page_content,
),
);
$page_content = ['#markup' => $page_content];
}
$content = $this->drupalRender($page_content);
if (!empty($page_content)) {
drupal_process_attached($page_content);
}
$cache = !empty($page_content['#cache']['tags']) ? array('tags' => $page_content['#cache']['tags']) : array();
$fragment = new HtmlFragment($content, $cache);
$fragment = $this->renderHtmlRenderer->render($page_content);
// A title defined in the return always wins.
if (isset($page_content['#title'])) {
$fragment->setTitle($page_content['#title'], Title::FILTER_XSS_ADMIN);
}
else if ($route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) {
if (!$fragment->getTitle() && $route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) {
$fragment->setTitle($this->titleResolver->getTitle($request, $route), Title::PASS_THROUGH);
}
// Add feed links from the page content.
$attached = isset($page_content['#attached']) ? $page_content['#attached'] : array();
if (!empty($attached['drupal_add_feed'])) {
foreach ($attached['drupal_add_feed'] as $feed) {
$feed_link = new FeedLinkElement($feed[1], $this->urlGenerator->generateFromPath($feed[0]));
$fragment->addLinkElement($feed_link);
}
}
return $fragment;
}
/**
* Wraps drupal_render().
*
* @todo: Remove as part of https://drupal.org/node/2182149
*/
protected function drupalRender(&$elements, $is_recursive_call = FALSE) {
return drupal_render($elements, $is_recursive_call);
}
}
......@@ -7,7 +7,7 @@
namespace Drupal\Core\Controller;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Page\RenderHtmlRendererInterface;
use Symfony\Component\HttpFoundation\Request;
/**
......@@ -29,11 +29,11 @@ class HtmlPageController extends HtmlControllerBase {
* The controller resolver.
* @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
* The title resolver.
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The url generator.
* @param \Drupal\Core\Page\RenderHtmlRendererInterface $render_html_renderer
* The render array to HTML fragment renderer.
*/
public function __construct(ControllerResolverInterface $controller_resolver, TitleResolverInterface $title_resolver, UrlGeneratorInterface $url_generator) {
parent::__construct($title_resolver, $url_generator);
public function __construct(ControllerResolverInterface $controller_resolver, TitleResolverInterface $title_resolver, RenderHtmlRendererInterface $render_html_renderer) {
parent::__construct($title_resolver, $render_html_renderer);
$this->controllerResolver = $controller_resolver;
}
......
<?php
/**
* @file
* Contains \Drupal\Core\Page\RenderHtmlRenderer.
*/
namespace Drupal\Core\Page;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Utility\Title;
/**
* Provides an implementation for an render array to HTML fragment renderer.
*
* This renderer takes into account the cache information, the attached assets
* as well as the title and HTML HEAD elements.
*/
class RenderHtmlRenderer implements RenderHtmlRendererInterface {
/**
* The URL generator.
*
* @var \Drupal\Core\Routing\UrlGeneratorInterface
*/
protected $urlGenerator;
/**
* Constructs a new RenderHtmlRenderer.
*
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The URL generator.
*/
public function __construct(UrlGeneratorInterface $url_generator) {
$this->urlGenerator = $url_generator;
}
/**
* {@inheritdoc}
*/
public function render(array $render_array) {
$content = $this->drupalRender($render_array);
if (!empty($render_array)) {
drupal_process_attached($render_array);
}
$cache = !empty($render_array['#cache']['tags']) ? ['tags' => $render_array['#cache']['tags']] : [];
$fragment = new HtmlFragment($content, $cache);
if (isset($render_array['#title'])) {
$fragment->setTitle($render_array['#title'], Title::FILTER_XSS_ADMIN);
}
$attached = isset($render_array['#attached']) ? $render_array['#attached'] : [];
$attached += [
'drupal_add_feed' => [],
'drupal_add_html_head' => [],
'drupal_add_html_head_link' => [],
];
// Add feed links from the page content.
foreach ($attached['drupal_add_feed'] as $feed) {
$fragment->addLinkElement(new FeedLinkElement($feed[1], $this->urlGenerator->generateFromPath($feed[0])));
}
// Add generic links from the page content.
foreach ($attached['drupal_add_html_head_link'] as $link) {
$fragment->addLinkElement(new LinkElement($this->urlGenerator->generateFromPath($link[0]['href']), $link[0]['rel']));
}
// @todo Also transfer the contents of "drupal_add_html_head" once
// https://www.drupal.org/node/2296951 lands.
// @todo Transfer CSS and JS over to the fragment once those are supported
// on the fragment object.
return $fragment;
}
/**
* Wraps drupal_render().
*
* @todo: Convert drupal_render into a proper injectable service.
*/
protected function drupalRender(&$elements, $is_recursive_call = FALSE) {
return drupal_render($elements, $is_recursive_call);
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Page\RenderHtmlRendererInterface.
*/
namespace Drupal\Core\Page;
/**
* Interface for a render array to HTML fragment renderer.
*
* An HTML Fragment Renderer is responsible for translating a Drupal render
* array into an HtmlFragmentInterface object.
*/
interface RenderHtmlRendererInterface {
/**
* Converts a render array into a corresponding HtmlFragment object.
*
* @param array $render_array
* The render array to convert.
*
* @return \Drupal\Core\Page\HtmlFragment
* The equivalent HtmlFragment object.
*
* @todo Change this documentation once https://www.drupal.org/node/2339475 lands.
*/
public function render(array $render_array);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment