core/core.services.yml | 4 +++- core/lib/Drupal/Core/Entity/EntityViewBuilder.php | 1 - core/lib/Drupal/Core/Render/Renderer.php | 24 +++++++++++++++++++--- core/modules/block/src/BlockViewBuilder.php | 6 +----- .../src/Tests/BlockContentCacheTagsTest.php | 3 ++- core/modules/filter/src/Tests/FilterAPITest.php | 5 ++++- .../modules/node/src/Tests/NodeListBuilderTest.php | 3 ++- .../modules/node/src/Tests/Views/FrontPageTest.php | 10 +++++++-- .../Tests/Cache/PageCacheTagsIntegrationTest.php | 3 ++- .../src/Tests/Entity/EntityCacheTagsTestBase.php | 8 +++++--- .../src/Tests/Entity/EntityListBuilderTest.php | 3 ++- .../src/Tests/Entity/EntityViewBuilderTest.php | 8 +++++--- core/modules/views/src/Entity/View.php | 5 +++-- core/modules/views/src/Tests/GlossaryTest.php | 3 ++- .../views/src/Tests/RenderCacheIntegrationTest.php | 3 ++- .../Tests/Core/Render/RendererBubblingTest.php | 4 ++++ .../Core/Render/RendererPostRenderCacheTest.php | 11 ++++++++++ .../Drupal/Tests/Core/Render/RendererTest.php | 5 ++++- .../Drupal/Tests/Core/Render/RendererTestBase.php | 15 +++++++++++++- sites/default/default.services.yml | 8 ++++++++ 20 files changed, 103 insertions(+), 29 deletions(-) diff --git a/core/core.services.yml b/core/core.services.yml index 8ce9b11..ecc7290 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1,6 +1,8 @@ parameters: session.storage.options: {} twig.config: {} + renderer.config: + required_cache_contexts: ['languages:language_interface', 'theme'] factory.keyvalue: default: keyvalue.database factory.keyvalue.expirable: @@ -1324,6 +1326,6 @@ services: lazy: true renderer: class: Drupal\Core\Render\Renderer - arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@request_stack', '@cache_factory', '@cache_contexts'] + arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@request_stack', '@cache_factory', '@cache_contexts', '%renderer.config%'] email.validator: class: Egulias\EmailValidator\EmailValidator diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index 071de3e..d12d028 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -170,7 +170,6 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco '#cache' => array( 'tags' => Cache::mergeTags($this->getCacheTags(), $entity->getCacheTags()), 'contexts' => [ - 'theme', 'user.roles', ], ), diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php index a7f7346..e021b9e 100644 --- a/core/lib/Drupal/Core/Render/Renderer.php +++ b/core/lib/Drupal/Core/Render/Renderer.php @@ -65,6 +65,13 @@ class Renderer implements RendererInterface { protected $cacheContexts; /** + * The renderer configuration array. + * + * @var array + */ + protected $rendererConfig; + + /** * The stack containing bubbleable rendering metadata. * * @var \SplStack|null @@ -86,14 +93,17 @@ class Renderer implements RendererInterface { * The cache factory. * @param \Drupal\Core\Cache\CacheContexts $cache_contexts * The cache contexts service. + * @param array $renderer_config + * The renderer configuration array. */ - public function __construct(ControllerResolverInterface $controller_resolver, ThemeManagerInterface $theme, ElementInfoManagerInterface $element_info, RequestStack $request_stack, CacheFactoryInterface $cache_factory, CacheContexts $cache_contexts) { + public function __construct(ControllerResolverInterface $controller_resolver, ThemeManagerInterface $theme, ElementInfoManagerInterface $element_info, RequestStack $request_stack, CacheFactoryInterface $cache_factory, CacheContexts $cache_contexts, array $renderer_config) { $this->controllerResolver = $controller_resolver; $this->theme = $theme; $this->elementInfo = $element_info; $this->requestStack = $request_stack; $this->cacheFactory = $cache_factory; $this->cacheContexts = $cache_contexts; + $this->rendererConfig = $renderer_config; } /** @@ -164,10 +174,19 @@ protected function doRender(&$elements, $is_root_call = FALSE) { } static::$stack->push(new BubbleableMetadata()); + // Bubbleable rendering metadata that has configurable defaults. + $required_cache_contexts = $this->rendererConfig['required_cache_contexts']; + if (isset($elements['#cache']['contexts'])) { + $elements['#cache']['contexts'] = Cache::mergeContexts($elements['#cache']['contexts'], $required_cache_contexts); + } + else { + $elements['#cache']['contexts'] = $required_cache_contexts; + } + // Try to fetch the prerendered element from cache, run any // #post_render_cache callbacks and return the final markup. $pre_bubbling_cid = NULL; - if (isset($elements['#cache'])) { + if (isset($elements['#cache']['keys']) || isset($elements['#cache']['cid'])) { $cached_element = $this->cacheGet($elements); if ($cached_element !== FALSE) { $elements = $cached_element; @@ -216,7 +235,6 @@ protected function doRender(&$elements, $is_root_call = FALSE) { } // Defaults for bubbleable rendering metadata. - $elements['#cache']['contexts'] = isset($elements['#cache']['contexts']) ? $elements['#cache']['contexts'] : array(); $elements['#cache']['tags'] = isset($elements['#cache']['tags']) ? $elements['#cache']['tags'] : array(); $elements['#cache']['max-age'] = isset($elements['#cache']['max-age']) ? $elements['#cache']['max-age'] : Cache::PERMANENT; $elements['#attached'] = isset($elements['#attached']) ? $elements['#attached'] : array(); diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php index d527d6d..2c94d61 100644 --- a/core/modules/block/src/BlockViewBuilder.php +++ b/core/modules/block/src/BlockViewBuilder.php @@ -86,14 +86,10 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la 'block', $entity->id(), ); - $default_cache_contexts = array( - 'languages', - 'theme', - ); $max_age = $plugin->getCacheMaxAge(); $build[$entity_id]['#cache'] += array( 'keys' => array_merge($default_cache_keys, $plugin->getCacheKeys()), - 'contexts' => array_merge($default_cache_contexts, $plugin->getCacheContexts()), + 'contexts' => $plugin->getCacheContexts(), 'expire' => ($max_age === Cache::PERMANENT) ? Cache::PERMANENT : REQUEST_TIME + $max_age, ); } diff --git a/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php b/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php index d5a98f6..56d952f 100644 --- a/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php +++ b/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Language\LanguageInterface; use Drupal\field\Entity\FieldStorageConfig; use Drupal\system\Tests\Entity\EntityCacheTagsTestBase; use Symfony\Component\HttpFoundation\Request; @@ -80,7 +81,7 @@ public function testBlock() { // Expected keys, contexts, and tags for the block. // @see \Drupal\block\BlockViewBuilder::viewMultiple() $expected_block_cache_keys = ['entity_view', 'block', $block->id()]; - $expected_block_cache_contexts = ['languages', 'theme']; + $expected_block_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme']; $expected_block_cache_tags = Cache::mergeTags(['block_view', 'rendered'], $block->getCacheTags(), $block->getPlugin()->getCacheTags()); // Expected contexts and tags for the BlockContent entity. diff --git a/core/modules/filter/src/Tests/FilterAPITest.php b/core/modules/filter/src/Tests/FilterAPITest.php index fe54ccd..5a12bc5 100644 --- a/core/modules/filter/src/Tests/FilterAPITest.php +++ b/core/modules/filter/src/Tests/FilterAPITest.php @@ -262,8 +262,11 @@ function testProcessedTextElement() { $expected_cache_contexts = [ // The cache context set by the filter_test_cache_contexts filter. 'languages:' . LanguageInterface::TYPE_CONTENT, + // The default cache contexts for Renderer. + 'languages:' . LanguageInterface::TYPE_INTERFACE, + 'theme', ]; - $this->assertEqual($expected_cache_contexts, $build['#cache']['contexts'], 'Expected cache contexts present.'); + $this->assertEqual($expected_cache_contexts, $build['#cache']['contexts']); //, 'Expected cache contexts present.'); $expected_markup = '

Hello, world!

This is a dynamic llama.

'; $this->assertEqual($expected_markup, $build['#markup'], 'Expected #post_render_cache callback has been applied.'); } diff --git a/core/modules/node/src/Tests/NodeListBuilderTest.php b/core/modules/node/src/Tests/NodeListBuilderTest.php index ec4b1ea..7e79b8d 100644 --- a/core/modules/node/src/Tests/NodeListBuilderTest.php +++ b/core/modules/node/src/Tests/NodeListBuilderTest.php @@ -7,6 +7,7 @@ namespace Drupal\node\Tests; +use Drupal\Core\Language\LanguageInterface; use Drupal\simpletest\KernelTestBase; /** @@ -38,7 +39,7 @@ public function testCacheContexts() { $build = $list_builder->render(); $this->container->get('renderer')->render($build); - $this->assertEqual(['url.query_args.pagers:0', 'user.node_grants:view'], $build['#cache']['contexts']); + $this->assertEqual(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0', 'user.node_grants:view'], $build['#cache']['contexts']); } } diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/src/Tests/Views/FrontPageTest.php index ed6fd3d..b8a6910 100644 --- a/core/modules/node/src/Tests/Views/FrontPageTest.php +++ b/core/modules/node/src/Tests/Views/FrontPageTest.php @@ -8,6 +8,7 @@ namespace Drupal\node\Tests\Views; use Drupal\Core\Cache\Cache; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; use Drupal\node\Entity\Node; use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; @@ -241,7 +242,13 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { $view = Views::getView('frontpage'); $view->setDisplay('page_1'); - $cache_contexts = ['user.node_grants:view', 'languages']; + $cache_contexts = [ + // Cache contexts associated with the view. + 'user.node_grants:view', + 'languages:' . LanguageInterface::TYPE_INTERFACE, + // Default cache contexts of the renderer. + 'theme', + ]; // Test before there are any nodes. $empty_node_listing_cache_tags = [ @@ -280,7 +287,6 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { $node->save(); } $cache_contexts = Cache::mergeContexts($cache_contexts, [ - 'theme', 'timezone', 'user.roles' ]); diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php b/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php index 8078913..1fbfcfd 100644 --- a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php +++ b/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Cache; +use Drupal\Core\Language\LanguageInterface; use Drupal\simpletest\WebTestBase; /** @@ -68,7 +69,7 @@ function testPageCacheTags() { )); $cache_contexts = [ - 'languages', + 'languages:' . LanguageInterface::TYPE_INTERFACE, 'route.menu_active_trails:account', 'route.menu_active_trails:footer', 'route.menu_active_trails:main', diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php index 3b382e1..df0b6d7 100644 --- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php @@ -10,6 +10,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Entity\FieldConfig; @@ -315,7 +316,8 @@ public function testReferencedEntity() { $nonempty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_labels_alphabetically', ['entity_type_id' => $entity_type]); // The default cache contexts for rendered entities. - $entity_cache_contexts = ['theme', 'user.roles']; + $default_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme']; + $entity_cache_contexts = Cache::mergeContexts($default_cache_contexts, ['user.roles']); // Cache tags present on every rendered page. $page_cache_tags = Cache::mergeTags( @@ -395,7 +397,7 @@ public function testReferencedEntity() { $this->verifyPageCache($empty_entity_listing_url, 'HIT', $empty_entity_listing_cache_tags); // Verify the entity type's list cache contexts are present. $contexts_in_header = $this->drupalGetHeader('X-Drupal-Cache-Contexts'); - $this->assertEqual($this->getAdditionalCacheContextsForEntityListing(), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header)); + $this->assertEqual(Cache::mergeContexts($default_cache_contexts, $this->getAdditionalCacheContextsForEntityListing()), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header)); $this->pass("Test listing containing referenced entity.", 'Debug'); @@ -405,7 +407,7 @@ public function testReferencedEntity() { $this->verifyPageCache($nonempty_entity_listing_url, 'HIT', $nonempty_entity_listing_cache_tags); // Verify the entity type's list cache contexts are present. $contexts_in_header = $this->drupalGetHeader('X-Drupal-Cache-Contexts'); - $this->assertEqual($this->getAdditionalCacheContextsForEntityListing(), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header)); + $this->assertEqual(Cache::mergeContexts($default_cache_contexts, $this->getAdditionalCacheContextsForEntityListing()), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header)); // Verify that after modifying the referenced entity, there is a cache miss diff --git a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php b/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php index fa5097a..336c836 100644 --- a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php +++ b/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Entity; +use Drupal\Core\Language\LanguageInterface; use Drupal\simpletest\WebTestBase; /** @@ -66,7 +67,7 @@ public function testCacheContexts() { $build = $list_builder->render(); $this->container->get('renderer')->render($build); - $this->assertEqual(['entity_test_view_grants', 'url.query_args.pagers:0'], $build['#cache']['contexts']); + $this->assertEqual(['entity_test_view_grants', 'languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0'], $build['#cache']['contexts']); } } diff --git a/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php b/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php index 1588150..6e87d2d 100644 --- a/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php +++ b/core/modules/system/src/Tests/Entity/EntityViewBuilderTest.php @@ -7,7 +7,9 @@ namespace Drupal\system\Tests\Entity; +use Drupal\Core\Language\LanguageInterface; use Drupal\entity_reference\Tests\EntityReferenceTestTrait; +use Drupal\Core\Cache\Cache; use Drupal\user\Entity\Role; use Drupal\user\RoleInterface; @@ -61,7 +63,7 @@ public function testEntityViewBuilderCache() { // Get a fully built entity view render array. $entity_test->save(); $build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full'); - $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts->convertTokensToKeys($build['#cache']['contexts'])); + $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts->convertTokensToKeys(Cache::mergeContexts($build['#cache']['contexts'], ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme']))); $cid = implode(':', $cid_parts); $bin = $build['#cache']['bin']; @@ -111,7 +113,7 @@ public function testEntityViewBuilderCacheWithReferences() { // Get a fully built entity view render array for the referenced entity. $build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test_reference, 'full'); - $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts->convertTokensToKeys($build['#cache']['contexts'])); + $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts->convertTokensToKeys(Cache::mergeContexts($build['#cache']['contexts'], ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme']))); $cid_reference = implode(':', $cid_parts); $bin_reference = $build['#cache']['bin']; @@ -130,7 +132,7 @@ public function testEntityViewBuilderCacheWithReferences() { // Get a fully built entity view render array. $build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full'); - $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts->convertTokensToKeys($build['#cache']['contexts'])); + $cid_parts = array_merge($build['#cache']['keys'], $cache_contexts->convertTokensToKeys(Cache::mergeContexts($build['#cache']['contexts'], ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme']))); $cid = implode(':', $cid_parts); $bin = $build['#cache']['bin']; diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 24d1ec3..3a21a13 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -11,6 +11,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Language\LanguageInterface; use Drupal\views\Views; use Drupal\views\ViewEntityInterface; @@ -316,9 +317,9 @@ protected function addCacheMetadata() { $executable->setDisplay($display_id); list($display['cache_metadata']['cacheable'], $display['cache_metadata']['contexts']) = $executable->getDisplay()->calculateCacheMetadata(); - // Always include at least the 'languages' context as there will most + // Always include at least the 'languages:' context as there will most // probably be translatable strings in the view output. - $display['cache_metadata']['contexts'] = Cache::mergeContexts($display['cache_metadata']['contexts'], ['languages']); + $display['cache_metadata']['contexts'] = Cache::mergeContexts($display['cache_metadata']['contexts'], ['languages:' . LanguageInterface::TYPE_INTERFACE]); } // Restore the previous active display. $executable->setDisplay($current_display); diff --git a/core/modules/views/src/Tests/GlossaryTest.php b/core/modules/views/src/Tests/GlossaryTest.php index 1df4701..93b6559 100644 --- a/core/modules/views/src/Tests/GlossaryTest.php +++ b/core/modules/views/src/Tests/GlossaryTest.php @@ -8,6 +8,7 @@ namespace Drupal\views\Tests; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; use Drupal\views\Views; @@ -87,7 +88,7 @@ public function testGlossaryView() { // Verify cache tags. $this->enablePageCaching(); - $this->assertPageCacheContextsAndTags(Url::fromRoute('view.glossary.page_1'), ['languages', 'url', 'user'], [ + $this->assertPageCacheContextsAndTags(Url::fromRoute('view.glossary.page_1'), ['languages:' . LanguageInterface::TYPE_INTERFACE, 'url', 'theme', 'user'], [ 'config:views.view.glossary', 'node:' . $nodes_by_char['a'][0]->id(), 'node:' . $nodes_by_char['a'][1]->id(), 'node:' . $nodes_by_char['a'][2]->id(), 'node_list', diff --git a/core/modules/views/src/Tests/RenderCacheIntegrationTest.php b/core/modules/views/src/Tests/RenderCacheIntegrationTest.php index 4a9276f..144f868 100644 --- a/core/modules/views/src/Tests/RenderCacheIntegrationTest.php +++ b/core/modules/views/src/Tests/RenderCacheIntegrationTest.php @@ -8,6 +8,7 @@ namespace Drupal\views\Tests; use Drupal\Core\Cache\Cache; +use Drupal\Core\Language\LanguageInterface; use Drupal\entity_test\Entity\EntityTest; use Drupal\views\Views; use Drupal\views\Entity\View; @@ -221,7 +222,7 @@ public function testViewAddCacheMetadata() { $view = View::load('test_display'); $view->save(); - $this->assertEqual(['languages', 'user', 'user.node_grants:view'], $view->getDisplay('default')['cache_metadata']['contexts']); + $this->assertEqual(['languages:' . LanguageInterface::TYPE_INTERFACE, 'user', 'user.node_grants:view'], $view->getDisplay('default')['cache_metadata']['contexts']); } } diff --git a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php index e2cfd91..7e1dc36 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php @@ -22,6 +22,10 @@ class RendererBubblingTest extends RendererTestBase { * {@inheritdoc} */ protected function setUp() { + // Disable the required cache contexts, so that this test can test just the + // bubbling behavior. + $this->rendererConfig['required_cache_contexts'] = []; + parent::setUp(); $this->setUpRequest(); diff --git a/core/tests/Drupal/Tests/Core/Render/RendererPostRenderCacheTest.php b/core/tests/Drupal/Tests/Core/Render/RendererPostRenderCacheTest.php index 53e30d6..c180657 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererPostRenderCacheTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererPostRenderCacheTest.php @@ -18,6 +18,17 @@ class RendererPostRenderCacheTest extends RendererTestBase { /** + * {@inheritdoc} + */ + protected function setUp() { + // Disable the required cache contexts, so that this test can test just the + // #post_render_cache behavior. + $this->rendererConfig['required_cache_contexts'] = []; + + parent::setUp(); + } + + /** * Generates an element with a #post_render_cache callback. * * @return array diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php index a53155f..069e238 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php @@ -19,7 +19,10 @@ class RendererTest extends RendererTestBase { protected $defaultThemeVars = [ '#cache' => [ - 'contexts' => [], + 'contexts' => [ + 'languages:language_interface', + 'theme', + ], 'tags' => [], 'max-age' => Cache::PERMANENT, ], diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php index b4320c9..b1c21c5 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php @@ -9,6 +9,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\MemoryBackend; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Render\Element; use Drupal\Core\Render\Renderer; use Drupal\Tests\UnitTestCase; @@ -70,6 +71,18 @@ class RendererTestBase extends UnitTestCase { protected $memoryCache; /** + * The mocked renderer configuration. + * + * @var array + */ + protected $rendererConfig = [ + 'required_cache_contexts' => [ + 'languages:language_interface', + 'theme', + ], + ]; + + /** * {@inheritdoc} */ protected function setUp() { @@ -83,7 +96,7 @@ protected function setUp() { $this->cacheContexts = $this->getMockBuilder('Drupal\Core\Cache\CacheContexts') ->disableOriginalConstructor() ->getMock(); - $this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->requestStack, $this->cacheFactory, $this->cacheContexts); + $this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->requestStack, $this->cacheFactory, $this->cacheContexts, $this->rendererConfig); $container = new ContainerBuilder(); $container->set('renderer', $this->renderer); diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml index 77e99cc..fbf4566 100644 --- a/sites/default/default.services.yml +++ b/sites/default/default.services.yml @@ -76,6 +76,14 @@ parameters: # Not recommended in production environments # @default true cache: true + renderer.config: + # Renderer required cache contexts: + # + # The Renderer will automatically associate these cache contexts with every + # render array, hence varying every render array by these cache contexts. + # + # @default ['languages:language_interface', 'theme'] + default_cache_contexts: ['languages:language_interface', 'theme'] factory.keyvalue: {} # Default key/value storage service to use.