diff --git a/core/includes/common.inc b/core/includes/common.inc index 6d91783d0e40697f83d8b7fd4b5e76851c519211..a2226c83f419d248f660af07742ac8a1047a54c4 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3990,6 +3990,12 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { $suffix = isset($elements['#suffix']) ? $elements['#suffix'] : ''; $elements['#markup'] = $prefix . $elements['#children'] . $suffix; + // Collect all cache tags. This allows the caller of drupal_render() to also + // access the complete list of cache tags. + if (!$is_recursive_call || isset($elements['#cache'])) { + $elements['#cache']['tags'] = drupal_render_collect_cache_tags($elements); + } + // Cache the processed element if #cache is set. if (isset($elements['#cache'])) { drupal_render_cache_set($elements['#markup'], $elements); @@ -4196,10 +4202,14 @@ function drupal_render_cache_set(&$markup, array $elements) { $data['#post_render_cache'] = $elements['#post_render_cache']; } + // Persist cache tags associated with this element. + if (isset($elements['#cache']['tags'])) { + $data['#cache']['tags'] = $elements['#cache']['tags']; + } + $bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'cache'; $expire = isset($elements['#cache']['expire']) ? $elements['#cache']['expire'] : Cache::PERMANENT; - $tags = drupal_render_collect_cache_tags($elements); - \Drupal::cache($bin)->set($cid, $data, $expire, $tags); + \Drupal::cache($bin)->set($cid, $data, $expire, $elements['#cache']['tags']); } /** diff --git a/core/includes/theme.inc b/core/includes/theme.inc index cfd84278b3d5c5d18453e5c5562284c7ef10657d..f699d4bfc9fb6f4a086e8062e4820eb32378f02b 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1967,14 +1967,6 @@ function template_preprocess_html(&$variables) { } } - // Initializes attributes which are specific to the html and body elements. - $variables['html_attributes'] = new Attribute; - - // HTML element attributes. - $language_interface = \Drupal::service('language_manager')->getCurrentLanguage(); - $variables['html_attributes']['lang'] = $language_interface->id; - $variables['html_attributes']['dir'] = $language_interface->direction ? 'rtl' : 'ltr'; - $site_config = \Drupal::config('system.site'); // Construct page title. if ($page->hasTitle()) { diff --git a/core/lib/Drupal/Core/Controller/HtmlControllerBase.php b/core/lib/Drupal/Core/Controller/HtmlControllerBase.php index 9cc76519b52f43160735fc92393c9887d0a1485c..6b81e7e1291afc73f4e42a350d554a45a4bbbd9a 100644 --- a/core/lib/Drupal/Core/Controller/HtmlControllerBase.php +++ b/core/lib/Drupal/Core/Controller/HtmlControllerBase.php @@ -71,9 +71,9 @@ protected function createHtmlFragment($page_content, Request $request) { ); } - $cache_tags = $this->drupalRenderCollectCacheTags($page_content); - $cache = !empty($cache_tags) ? array('tags' => $cache_tags) : array(); - $fragment = new HtmlFragment($this->drupalRender($page_content), $cache); + $content = $this->drupalRender($page_content); + $cache = !empty($page_content['#cache']['tags']) ? array('tags' => $page_content['#cache']['tags']) : array(); + $fragment = new HtmlFragment($content, $cache); // A title defined in the return always wins. if (isset($page_content['#title'])) { @@ -95,13 +95,4 @@ protected function drupalRender(&$elements, $is_recursive_call = FALSE) { return drupal_render($elements, $is_recursive_call); } - /** - * Wraps drupal_render_collect_cache_tags() - * - * @todo: Remove as part of https://drupal.org/node/2182149 - */ - protected function drupalRenderCollectCacheTags($element, $tags = array()) { - return drupal_render_collect_cache_tags($element, $tags); - } - } diff --git a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php index 6e0c5095e739637f6c551aba2ecc4585025c91cb..e1a9029c5a77561ac922f202b3d54cb517707963 100644 --- a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php +++ b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php @@ -48,15 +48,14 @@ public function render(HtmlFragment $fragment, $status_code = 200) { // hook_page_build(). This adds the other regions to the page. $page_array = drupal_prepare_page($page_content); - // Collect cache tags for all the content in all the regions on the page. - $tags = drupal_render_collect_cache_tags($page_array); - // Build the HtmlPage object. - $page = new HtmlPage('', array('tags' => $tags), $fragment->getTitle()); + $page = new HtmlPage('', array(), $fragment->getTitle()); $page = $this->preparePage($page, $page_array); $page->setBodyTop(drupal_render($page_array['page_top'])); $page->setBodyBottom(drupal_render($page_array['page_bottom'])); $page->setContent(drupal_render($page_array)); + // Collect cache tags for all the content in all the regions on the page. + $page->setCacheTags($page_array['#cache']['tags']); $page->setStatusCode($status_code); return $page; diff --git a/core/lib/Drupal/Core/Page/HtmlPage.php b/core/lib/Drupal/Core/Page/HtmlPage.php index c2f09edc5a4b4c2ce1391caf42916ce7766778ec..f8725c4ef4a0a8810494330d4274f2e75c73964e 100644 --- a/core/lib/Drupal/Core/Page/HtmlPage.php +++ b/core/lib/Drupal/Core/Page/HtmlPage.php @@ -158,5 +158,15 @@ public function getStatusCode() { return $this->statusCode; } + /** + * Sets the cache tags associated with this HTML page. + * + * @param array $cache_tags + * The cache tags associated with this HTML page. + */ + public function setCacheTags(array $cache_tags) { + $this->cache['tags'] = $cache_tags; + } + } diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php index 3ca1f19f34d3f209f0468bd07c41a90ca539d25e..7f961d3662a23d5706f29e902be4ca0bc9ae9c9b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php @@ -65,7 +65,7 @@ function testPageCacheTags() { $cid_parts = array(url($path, array('absolute' => TRUE)), 'html'); $cid = sha1(implode(':', $cid_parts)); $cache_entry = \Drupal::cache('page')->get($cid); - $this->assertIdentical($cache_entry->tags, array('content:1', 'system_test_cache_tags_page:1')); + $this->assertIdentical($cache_entry->tags, array('content:1', 'system_test_cache_tags_page:1', 'pre_render:1')); Cache::invalidateTags($tags); $this->drupalGet($path); diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php index b2d7eb01b03a80f619dabdc1ef54c62f171b75e9..14ce9266dc1f76fc4efecbe8c3a958edde668dde 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php @@ -500,6 +500,7 @@ function testDrupalRenderPostRenderCache() { '#markup' => '

#cache enabled, GET

', '#attached' => $test_element['#attached'], '#post_render_cache' => $test_element['#post_render_cache'], + '#cache' => array('tags' => array()), ); $this->assertIdentical($cached_element, $expected_element, 'The correct data is cached: the stored #markup and #attached properties are not affected by #post_render_cache callbacks.'); @@ -619,6 +620,7 @@ function testDrupalRenderChildrenPostRenderCache() { $context_3, ) ), + '#cache' => array('tags' => array()), ); $dom = Html::load($cached_element['#markup']); @@ -702,6 +704,7 @@ function testDrupalRenderChildrenPostRenderCache() { $context_3, ) ), + '#cache' => array('tags' => array()), ); $dom = Html::load($cached_parent_element['#markup']); @@ -727,6 +730,7 @@ function testDrupalRenderChildrenPostRenderCache() { $context_3, ) ), + '#cache' => array('tags' => array()), ); $dom = Html::load($cached_child_element['#markup']); @@ -830,6 +834,7 @@ function testDrupalRenderRenderCachePlaceholder() { $expected_token => $context, ), ), + '#cache' => array('tags' => array()), ); $this->assertIdentical($cached_element, $expected_element, 'The correct data is cached: the stored #markup and #attached properties are not affected by #post_render_cache callbacks.'); @@ -920,6 +925,7 @@ function testDrupalRenderChildElementRenderCachePlaceholder() { $expected_token => $context, ), ), + '#cache' => array('tags' => array()), ); $this->assertIdentical($cached_element, $expected_element, 'The correct data is cached for the child element: the stored #markup and #attached properties are not affected by #post_render_cache callbacks.'); @@ -944,6 +950,7 @@ function testDrupalRenderChildElementRenderCachePlaceholder() { $expected_token => $context, ), ), + '#cache' => array('tags' => array()), ); $this->assertIdentical($cached_element, $expected_element, 'The correct data is cached for the parent element: the stored #markup and #attached properties are not affected by #post_render_cache callbacks.'); @@ -972,6 +979,7 @@ function testDrupalRenderChildElementRenderCachePlaceholder() { $expected_token => $context, ), ), + '#cache' => array('tags' => array()), ); $this->assertIdentical($cached_element, $expected_element, 'The correct data is cached for the child element: the stored #markup and #attached properties are not affected by #post_render_cache callbacks.'); diff --git a/core/modules/system/tests/modules/ajax_test/lib/Drupal/ajax_test/Form/AjaxTestForm.php b/core/modules/system/tests/modules/ajax_test/lib/Drupal/ajax_test/Form/AjaxTestForm.php index 980d117b37dbacf43ac514b6a4eecea9f06841d2..462f6710e9e7dc19921a98643c6c847409b03cae 100644 --- a/core/modules/system/tests/modules/ajax_test/lib/Drupal/ajax_test/Form/AjaxTestForm.php +++ b/core/modules/system/tests/modules/ajax_test/lib/Drupal/ajax_test/Form/AjaxTestForm.php @@ -27,7 +27,6 @@ public function getFormId() { public function buildForm(array $form, array &$form_state) { $form['#action'] = url('ajax-test/dialog'); - $form['#cache'] = TRUE; $form['description'] = array( '#markup' => '

' . t("Ajax Form contents description.") . '

', diff --git a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php index 868117aebc20733ebd0f60c96f2198fa4b14d451..36a2c8ffffac72f1632f22182c1e4d8c8cde9831 100644 --- a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php +++ b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php @@ -41,14 +41,27 @@ public function lockExit() { /** * Set cache tag on on the returned render array. */ - function system_test_cache_tags_page() { + public function system_test_cache_tags_page() { $build['main'] = array( - '#markup' => 'Cache tags page example', '#cache' => array('tags' => array('system_test_cache_tags_page' => TRUE)), + '#pre_render' => array( + '\Drupal\system_test\Controller\SystemTestController::preRenderCacheTags', + ), + 'message' => array( + '#markup' => 'Cache tags page example', + ), ); return $build; } + /** + * Sets a cache tag on an element to help test #pre_render and cache tags. + */ + public static function preRenderCacheTags($elements) { + $elements['#cache']['tags']['pre_render'] = TRUE; + return $elements; + } + /** * @todo Remove system_test_authorize_init_page(). */