Commit 83c53707 authored by alexpott's avatar alexpott

Issue #2466585 by Wim Leers, Fabianx: Decouple cache implementation from the...

Issue #2466585 by Wim Leers, Fabianx: Decouple cache implementation from the renderer and expose as renderCache service
parent 8b9dfcef
......@@ -853,7 +853,7 @@ services:
- { name: event_subscriber }
main_content_renderer.html:
class: Drupal\Core\Render\MainContent\HtmlRenderer
arguments: ['@title_resolver', '@plugin.manager.display_variant', '@event_dispatcher', '@element_info', '@module_handler', '@renderer', '@cache_contexts_manager']
arguments: ['@title_resolver', '@plugin.manager.display_variant', '@event_dispatcher', '@element_info', '@module_handler', '@renderer', '@render_cache', '@cache_contexts_manager']
tags:
- { name: render.main_content_renderer, format: html }
main_content_renderer.ajax:
......@@ -1346,8 +1346,11 @@ services:
tags:
- { name: mime_type_guesser }
lazy: true
render_cache:
class: Drupal\Core\Render\RenderCache
arguments: ['@request_stack', '@cache_factory', '@cache_contexts_manager']
renderer:
class: Drupal\Core\Render\Renderer
arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@request_stack', '@cache_factory', '@cache_contexts_manager', '%renderer.config%']
arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@render_cache', '%renderer.config%']
email.validator:
class: Egulias\EmailValidator\EmailValidator
......@@ -16,7 +16,7 @@
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\Core\Render\PageDisplayVariantSelectionEvent;
use Drupal\Core\Render\Renderer;
use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Render\RenderEvents;
use Drupal\Core\Routing\RouteMatchInterface;
......@@ -72,6 +72,13 @@ class HtmlRenderer implements MainContentRendererInterface {
*/
protected $renderer;
/**
* The render cache service.
*
* @var \Drupal\Core\Render\RenderCacheInterface
*/
protected $renderCache;
/**
* The cache contexts manager service.
*
......@@ -94,16 +101,19 @@ class HtmlRenderer implements MainContentRendererInterface {
* The module handler.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
* @param \Drupal\Core\Cache\CacheContextsManager $cache_contexts_manager
* The cache contexts manager service.
*/
public function __construct(TitleResolverInterface $title_resolver, PluginManagerInterface $display_variant_manager, EventDispatcherInterface $event_dispatcher, ElementInfoManagerInterface $element_info_manager, ModuleHandlerInterface $module_handler, RendererInterface $renderer, CacheContextsManager $cache_contexts_manager) {
public function __construct(TitleResolverInterface $title_resolver, PluginManagerInterface $display_variant_manager, EventDispatcherInterface $event_dispatcher, ElementInfoManagerInterface $element_info_manager, ModuleHandlerInterface $module_handler, RendererInterface $renderer, RenderCacheInterface $render_cache, CacheContextsManager $cache_contexts_manager) {
$this->titleResolver = $title_resolver;
$this->displayVariantManager = $display_variant_manager;
$this->eventDispatcher = $event_dispatcher;
$this->elementInfoManager = $element_info_manager;
$this->moduleHandler = $module_handler;
$this->renderer = $renderer;
$this->renderCache = $render_cache;
$this->cacheContextsManager = $cache_contexts_manager;
}
......@@ -217,7 +227,7 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte
// @todo Remove this once https://www.drupal.org/node/2359901 lands.
if (!empty($main_content)) {
$this->renderer->render($main_content, FALSE);
$main_content = $this->renderer->getCacheableRenderArray($main_content) + [
$main_content = $this->renderCache->getCacheableRenderArray($main_content) + [
'#title' => isset($main_content['#title']) ? $main_content['#title'] : NULL
];
}
......
This diff is collapsed.
<?php
/**
* @file
* Contains \Drupal\Core\Render\RenderCacheInterface.
*/
namespace Drupal\Core\Render;
/**
* Defines an interface for caching rendered render arrays.
*
* @see sec_caching
*
* @see \Drupal\Core\Render\RendererInterface
*/
interface RenderCacheInterface {
/**
* Gets a cacheable render array for a render array and its rendered output.
*
* Given a render array and its rendered output (HTML string), return an array
* data structure that allows the render array and its associated metadata to
* be cached reliably (and is serialization-safe).
*
* If Drupal needs additional rendering metadata to be cached at some point,
* consumers of this method will continue to work. Those who only cache
* certain parts of a render array will cease to work.
*
* @param array $elements
* A render array, on which \Drupal\Core\Render\RendererInterface::render()
* has already been invoked.
*
* @return array
* An array representing the cacheable data for this render array.
*/
public function getCacheableRenderArray(array $elements);
/**
* Gets the cached, pre-rendered element of a renderable element from cache.
*
* @param array $elements
* A renderable array.
*
* @return array
* A renderable array, with the original element and all its children pre-
* rendered, or FALSE if no cached copy of the element is available.
*
* @see \Drupal\Core\Render\RendererInterface::render()
* @see ::set()
*/
public function get(array $elements);
/**
* Caches the rendered output of a renderable array.
*
* May be called by an implementation of \Drupal\Core\Render\RendererInterface
* while rendering, if the #cache property is set.
*
* @param array $elements
* A renderable array.
* @param array $pre_bubbling_elements
* A renderable array corresponding to the state (in particular, the
* cacheability metadata) of $elements prior to the beginning of its
* rendering process, and therefore before any bubbling of child
* information has taken place. Only the #cache property is used by this
* function, so the caller may omit all other properties and children from
* this array.
*
* @return bool|null
* Returns FALSE if no cache item could be created, NULL otherwise.
*
* @see ::get()
*/
public function set(array &$elements, array $pre_bubbling_elements);
}
This diff is collapsed.
......@@ -308,25 +308,6 @@ public function renderPlain(&$elements);
*/
public function render(&$elements, $is_root_call = FALSE);
/**
* Gets a cacheable render array for a render array and its rendered output.
*
* Given a render array and its rendered output (HTML string), return an array
* data structure that allows the render array and its associated metadata to
* be cached reliably (and is serialization-safe).
*
* If Drupal needs additional rendering metadata to be cached at some point,
* consumers of this method will continue to work. Those who only cache
* certain parts of a render array will cease to work.
*
* @param array $elements
* A renderable array, on which ::render() has already been invoked.
*
* @return array
* An array representing the cacheable data for this render array.
*/
public function getCacheableRenderArray(array $elements);
/**
* Merges the bubbleable rendering metadata o/t 2nd render array with the 1st.
*
......
......@@ -8,6 +8,7 @@
namespace Drupal\views\Plugin\views\cache;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\views\Plugin\views\PluginBase;
use Drupal\Core\Database\Query\Select;
......@@ -80,6 +81,13 @@ abstract class CachePluginBase extends PluginBase {
*/
protected $renderer;
/**
* The render cache service.
*
* @var \Drupal\Core\Render\RenderCacheInterface
*/
protected $renderCache;
/**
* Constructs a CachePluginBase object.
*
......@@ -91,11 +99,14 @@ abstract class CachePluginBase extends PluginBase {
* The plugin implementation definition.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The HTML renderer.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer, RenderCacheInterface $render_cache) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->renderer = $renderer;
$this->renderCache = $render_cache;
}
/**
......@@ -106,7 +117,8 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration,
$plugin_id,
$plugin_definition,
$container->get('renderer')
$container->get('renderer'),
$container->get('render_cache')
);
}
......@@ -190,7 +202,7 @@ public function cacheSet($type) {
// Also assign the cacheable render array back to the display handler so
// that is used to render the view for this request and rendering does
// not happen twice.
$this->storage = $this->view->display_handler->output = $this->renderer->getCacheableRenderArray($output);
$this->storage = $this->view->display_handler->output = $this->renderCache->getCacheableRenderArray($output);
\Drupal::cache($this->outputBin)->set($this->generateOutputKey(), $this->storage, $this->cacheSetExpire($type), Cache::mergeTags($this->storage['#cache']['tags'], ['rendered']));
break;
}
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\RendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface;
......@@ -51,10 +52,12 @@ class Time extends CachePluginBase {
* The HTML renderer.
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
* The date formatter service.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer, DateFormatter $date_formatter) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer, RenderCacheInterface $render_cache, DateFormatter $date_formatter) {
$this->dateFormatter = $date_formatter;
parent::__construct($configuration, $plugin_id, $plugin_definition, $renderer);
parent::__construct($configuration, $plugin_id, $plugin_definition, $renderer, $render_cache);
}
/**
......@@ -66,6 +69,7 @@ public static function create(ContainerInterface $container, array $configuratio
$plugin_id,
$plugin_definition,
$container->get('renderer'),
$container->get('render_cache'),
$container->get('date.formatter')
);
}
......
......@@ -71,9 +71,9 @@ public function testPostRenderCacheWithCacheDisabled() {
/**
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers ::cacheSet
* @covers ::createCacheID
* @covers \Drupal\Core\Render\RenderCache::get
* @covers \Drupal\Core\Render\RenderCache::set
* @covers \Drupal\Core\Render\RenderCache::createCacheID
*/
public function testPostRenderCacheWithColdCache() {
list($test_element, $context) = $this->generatePostRenderCacheElement();
......@@ -127,7 +127,7 @@ public function testPostRenderCacheWithColdCache() {
/**
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache
*/
public function testPostRenderCacheWithPostRequest() {
......@@ -189,7 +189,7 @@ public function testRenderRecursivePostRenderCache() {
*
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache
*/
public function testRenderChildrenPostRenderCacheDifferentContexts() {
......@@ -284,7 +284,7 @@ public function testRenderChildrenPostRenderCacheDifferentContexts() {
*
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache
*/
public function testRenderChildrenPostRenderCacheComplex() {
......@@ -404,7 +404,7 @@ public function testRenderChildrenPostRenderCacheComplex() {
*
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache
* @covers ::generateCachePlaceholder
*/
......
......@@ -531,9 +531,9 @@ public function testRenderWithThemeArguments() {
/**
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers ::cacheSet
* @covers ::createCacheID
* @covers \Drupal\Core\Render\RenderCache::get
* @covers \Drupal\Core\Render\RenderCache::set
* @covers \Drupal\Core\Render\RenderCache::createCacheID
*/
public function testRenderCache() {
$this->setUpRequest();
......@@ -584,9 +584,9 @@ public function testRenderCache() {
/**
* @covers ::render
* @covers ::doRender
* @covers ::cacheGet
* @covers ::cacheSet
* @covers ::createCacheID
* @covers \Drupal\Core\Render\RenderCache::get
* @covers \Drupal\Core\Render\RenderCache::set
* @covers \Drupal\Core\Render\RenderCache::createCacheID
*
* @dataProvider providerTestRenderCacheMaxAge
*/
......
......@@ -12,6 +12,7 @@
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Renderer;
use Drupal\Core\Render\RenderCache;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Request;
......@@ -29,6 +30,13 @@ class RendererTestBase extends UnitTestCase {
*/
protected $renderer;
/**
* The tested render cache.
*
* @var \Drupal\Core\Render\RenderCache
*/
protected $renderCache;
/**
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
......@@ -118,10 +126,12 @@ protected function setUp() {
}
return $keys;
});
$this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->requestStack, $this->cacheFactory, $this->cacheContextsManager, $this->rendererConfig);
$this->renderCache = new RenderCache($this->requestStack, $this->cacheFactory, $this->cacheContextsManager);
$this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->renderCache, $this->rendererConfig);
$container = new ContainerBuilder();
$container->set('cache_contexts_manager', $this->cacheContextsManager);
$container->set('render_cache', $this->renderCache);
$container->set('renderer', $this->renderer);
\Drupal::setContainer($container);
}
......
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