commit 83edfb0dafd85cb0bb536ae59820ea41b5b9839b
Author: Moshe Weitzman <weitzman@tejasa.com>
Date:   Sun Oct 27 13:24:09 2013 -0400

    Issue #2094241 by moshe weitzman, Wim Leers, amateescu | catch: Cache tag the page cache.

diff --git a/core/includes/common.inc b/core/includes/common.inc
index 54d4212..257b363 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3168,7 +3168,7 @@ function drupal_page_set_cache(Response $response, Request $request) {
         // because by the time it is read, the configuration might change.
         'page_compressed' => $page_compressed,
       ),
-      'tags' => array('content' => TRUE),
+      'tags' => array('content' => TRUE) + drupal_cache_tags_page_get(),
       'expire' => CacheBackendInterface::CACHE_PERMANENT,
       'created' => REQUEST_TIME,
     );
@@ -4206,6 +4206,38 @@ function drupal_render_collect_cache_tags($element, $tags = array()) {
 }
 
 /**
+ * A #post_render callback at the top level of the $page array. Collects the
+ * tags for use in page cache.
+ *
+ * @param string $children
+ *   An HTML string of rendered output.
+ * @param array $elements
+ *   A render array.
+ *
+ * @return string
+ *   The same $children that was passed in - no modifications.
+ */
+function drupal_post_render_cache_tags_page_set($children, array $elements) {
+  if (drupal_page_is_cacheable()) {
+    $tags = &drupal_static('system_cache_tags_page', array());
+    $tags = drupal_render_collect_cache_tags($elements);
+  }
+  return $children;
+}
+
+/**
+ * Return the cache tags that were stored during drupal_render_page().
+ *
+ * @return array
+ *   An array of cache tags.
+ *
+ * @see drupal_post_render_cache_tags_page_set()
+ */
+function drupal_cache_tags_page_get() {
+  return drupal_static('system_cache_tags_page', array());
+}
+
+/**
  * Prepares an element for caching based on a query.
  *
  * This smart caching strategy saves Drupal from querying and rendering to HTML
diff --git a/core/modules/node/lib/Drupal/node/NodeRenderController.php b/core/modules/node/lib/Drupal/node/NodeRenderController.php
index 433adb3..5201474 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -88,7 +88,7 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityDisp
 
     // The node 'submitted' info is not rendered in a standard way (renderable
     // array) so we have to add a cache tag manually.
-    $build['#cache']['tags']['user'][] = $entity->uid;
+    $build['#cache']['tags']['user'][] = $entity->getAuthorId();
   }
 
 }
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 89d8ff4..f80f92e 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php
@@ -42,6 +42,29 @@ function setUp() {
   }
 
   /**
+   * Assure that cache tags are properly persisted.
+   *
+   * Since tag based invalidation works, we know that our tag properly
+   * persisted.
+   */
+  function testPageCacheTags() {
+    $config = \Drupal::config('system.performance');
+    $config->set('cache.page.use_internal', 1);
+    $config->set('cache.page.max_age', 300);
+    $config->save();
+
+    $path = 'system-test/cache_tags_page';
+    $tags = array('system_test_cache_tags_page' => TRUE);
+    $this->drupalGet($path);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
+    $this->drupalGet($path);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
+    cache_invalidate_tags($tags);
+    $this->drupalGet($path);
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
+  }
+
+  /**
    * Tests support for different cache items with different Accept headers.
    */
   function testAcceptHeaderRequests() {
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 80b02f8..5153c81 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -261,6 +261,7 @@ function system_element_info() {
     '#theme_wrappers' => array('form'),
   );
   $types['page'] = array(
+    '#post_render' => array('drupal_post_render_cache_tags_page_set'),
     '#show_messages' => TRUE,
     '#theme' => 'page',
     '#theme_wrappers' => array('html'),
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 db4302f..058aabe 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
@@ -39,6 +39,17 @@ public function lockExit() {
   }
 
   /**
+   * Set cache tag on on the returned render array.
+   */
+  function system_test_cache_tags_page() {
+    $build['main'] = array(
+      '#markup' => 'Cache tags page example',
+      '#cache' => array('tags' => array('system_test_cache_tags_page' => TRUE)),
+    );
+    return $build;
+  }
+
+  /**
    * @todo Remove system_test_authorize_init_page().
    */
   public function authorizeInit($page_title) {
diff --git a/core/modules/system/tests/modules/system_test/system_test.routing.yml b/core/modules/system/tests/modules/system_test/system_test.routing.yml
index 4c6b565..660cfce 100644
--- a/core/modules/system/tests/modules/system_test/system_test.routing.yml
+++ b/core/modules/system/tests/modules/system_test/system_test.routing.yml
@@ -45,6 +45,13 @@ system_test.lock_exit:
   requirements:
     _access: 'TRUE'
 
+system_test.cache_tags_page:
+  path: '/system-test/cache_tags_page'
+  defaults:
+    _controller: '\Drupal\system_test\Controller\SystemTestController::system_test_cache_tags_page'
+  requirements:
+    _access: 'TRUE'
+
 system_test.authorize_init:
   path: '/system-test/authorize-init/{page_title}'
   defaults:
diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.module b/core/modules/system/tests/modules/test_page_test/test_page_test.module
index 5911afb..4fab773 100644
--- a/core/modules/system/tests/modules/test_page_test/test_page_test.module
+++ b/core/modules/system/tests/modules/test_page_test/test_page_test.module
@@ -22,5 +22,6 @@ function test_page_test_page() {
   return array(
     '#title' => t('Test page'),
     '#markup' => t('Test page text.'),
+    '#cache' => array('tags' => array('test-page' => TRUE)),
   );
 }
