diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 54b038b..5a7f327 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1200,6 +1200,12 @@ function template_preprocess(&$variables, $hook, $info) {
       $variables['attributes'] = NestedArray::mergeDeep($variables['attributes'], $variables[$key]['#attributes']);
     }
   }
+
+  // If this is an entity being rendered, call the preprocess() method on the
+  // view builder.
+  if (isset($variables['elements']['#entity_type']) && isset($variables['elements']['#view_mode'])) {
+    \Drupal::entityManager()->getViewBuilder($variables['elements']['#entity_type'])->preprocess($variables);
+  }
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index d212474..b9f165c 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -162,6 +162,7 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
         'contexts' => $entity->getCacheContexts(),
         'max-age' => $entity->getCacheMaxAge(),
       ),
+      '#entity_type' => $this->entityTypeId,
     );
 
     // Cache the rendered output if permitted by the view mode and global entity
@@ -362,7 +363,29 @@ public function resetCache(array $entities = NULL) {
   }
 
   /**
-   * Determines whether the view mode is cacheable.
+   * {@inheritdoc}
+   */
+  public function preprocess(array &$variables) {
+    // Only do anything if the entity follows the standard naming convention.
+    if (!isset($variables['elements']['#' . $this->entityTypeId])) {
+      return;
+    }
+
+    $variables['view_mode'] = $variables['elements']['#view_mode'];
+    $entity = $variables['elements']['#' . $this->entityTypeId];
+    $variables[$this->entityTypeId] = $entity;
+
+    // Helpful $content variable for templates.
+    $variables += array('content' => array());
+    foreach (Element::children($variables['elements']) as $key) {
+      $variables['content'][$key] = $variables['elements'][$key];
+    }
+
+    $variables['attributes']['class'][] = $this->entityTypeId;
+  }
+
+  /**
+   * Returns TRUE if the view mode is cacheable.
    *
    * @param string $view_mode
    *   Name of the view mode that should be rendered.
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
index eff6516..f9f36bf 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
@@ -156,4 +156,12 @@ public function viewFieldItem(FieldItemInterface $item, $display_options = array
    */
   public function getCacheTags();
 
+  /**
+   * Preprocesses variables.
+   *
+   * @param array $variables
+   *   An associative array containing the entity variables to be rendered.
+   */
+  public function preprocess(array &$variables);
+
 }
diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php
index 32c7bfe..2d3e1fe 100644
--- a/core/modules/block/src/BlockViewBuilder.php
+++ b/core/modules/block/src/BlockViewBuilder.php
@@ -252,4 +252,11 @@ public static function preRender($build) {
     return $build;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preprocess(array &$variables) {
+
+  }
+
 }
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 40b4e40..d3153dd 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -619,9 +619,8 @@ function comment_preprocess_block(&$variables) {
  */
 function template_preprocess_comment(&$variables) {
   /** @var \Drupal\comment\CommentInterface $comment */
-  $comment = $variables['elements']['#comment'];
+  $comment = $variables['comment'];
   $commented_entity = $comment->getCommentedEntity();
-  $variables['comment'] = $comment;
   $variables['commented_entity'] = $commented_entity;
   $variables['threaded'] = $variables['elements']['#comment_threaded'];
 
@@ -704,11 +703,6 @@ function template_preprocess_comment(&$variables) {
     $variables['parent'] = '';
   }
 
-  // Helpful $content variable for templates.
-  foreach (Element::children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
   // Set status to a string representation of comment->status.
   if (isset($comment->in_preview)) {
     $variables['status'] = 'preview';
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ebfd07f..3fa4f36 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -572,10 +572,8 @@ function node_theme_suggestions_node(array $variables) {
  *   - view_mode: View mode; e.g., 'full', 'teaser', etc.
  */
 function template_preprocess_node(&$variables) {
-  $variables['view_mode'] = $variables['elements']['#view_mode'];
   // Provide a distinct $teaser boolean.
   $variables['teaser'] = $variables['view_mode'] == 'teaser';
-  $variables['node'] = $variables['elements']['#node'];
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
   $variables['date'] = drupal_render($variables['elements']['created']);
@@ -593,12 +591,6 @@ function template_preprocess_node(&$variables) {
   //   - The node is in preview and view mode is either 'full' or 'default'.
   $variables['page'] = ($variables['view_mode'] == 'full' && (node_is_page($node)) || (isset($node->in_preview) && in_array($node->preview_view_mode, array('full', 'default'))));
 
-  // Helpful $content variable for templates.
-  $variables += array('content' => array());
-  foreach (Element::children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
   // Display post information only on certain node types.
   $node_type = $node->type->entity;
   // Used by RDF to add attributes around the author and date submitted.
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 0c7cf5c..b497b83 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -543,7 +543,8 @@ function rdf_preprocess_taxonomy_term(&$variables) {
   // The @about attribute specifies the URI of the resource described within
   // the HTML element, while the @typeof attribute indicates its RDF type
   // (e.g., schema:Thing, skos:Concept, and so on).
-  $term = $variables['term'];
+  /* @var \Drupal\taxonomy\TermInterface $term */
+  $term = $variables['taxonomy_term'];
   $mapping = rdf_get_mapping('taxonomy_term', $term->bundle());
   $bundle_mapping = $mapping->getPreparedBundleMapping();
   $variables['attributes']['about'] = $term->url();
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index a73f6fc..21be46e 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -239,22 +239,14 @@ function taxonomy_theme_suggestions_taxonomy_term(array $variables) {
  *   - attributes: HTML attributes for the containing element.
  */
 function template_preprocess_taxonomy_term(&$variables) {
-  $variables['view_mode'] = $variables['elements']['#view_mode'];
-  $variables['term'] = $variables['elements']['#taxonomy_term'];
   /** @var \Drupal\taxonomy\TermInterface $term */
-  $term = $variables['term'];
+  $term = $variables['taxonomy_term'];
 
   $variables['url'] = $term->url();
   // We use name here because that is what appears in the UI.
   $variables['name'] = $variables['elements']['name'];
   unset($variables['elements']['name']);
   $variables['page'] = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term);
-
-  // Helpful $content variable for templates.
-  $variables['content'] = array();
-  foreach (Element::children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
 }
 
 /**
diff --git a/core/modules/taxonomy/templates/taxonomy-term.html.twig b/core/modules/taxonomy/templates/taxonomy-term.html.twig
index 6636b79..eb23c3a 100644
--- a/core/modules/taxonomy/templates/taxonomy-term.html.twig
+++ b/core/modules/taxonomy/templates/taxonomy-term.html.twig
@@ -15,7 +15,7 @@
  *   @endcode
  * - attributes: HTML attributes for the wrapper.
  * - page: Flag for the full page state.
- * - term: The taxonomy term entity, including:
+ * - taxonomy_term: The taxonomy term entity, including:
  *   - id: The ID of the taxonomy term.
  *   - bundle: Machine name of the current vocabulary.
  * - view_mode: View mode, e.g. 'full', 'teaser', etc.
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 0e9cedb..7c84024 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1419,9 +1419,4 @@ function user_logout() {
  *   - attributes: HTML attributes for the containing element.
  */
 function template_preprocess_user(&$variables) {
-  $variables['user'] = $variables['elements']['#user'];
-  // Helpful $content variable for templates.
-  foreach (Element::children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
 }
diff --git a/core/themes/classy/templates/content/taxonomy-term.html.twig b/core/themes/classy/templates/content/taxonomy-term.html.twig
index 7e0446e..b381d5e 100644
--- a/core/themes/classy/templates/content/taxonomy-term.html.twig
+++ b/core/themes/classy/templates/content/taxonomy-term.html.twig
@@ -15,7 +15,7 @@
  *   @endcode
  * - attributes: HTML attributes for the wrapper.
  * - page: Flag for the full page state.
- * - term: The taxonomy term entity, including:
+ * - taxonomy_term: The taxonomy term entity, including:
  *   - id: The ID of the taxonomy term.
  *   - bundle: Machine name of the current vocabulary.
  * - view_mode: View mode, e.g. 'full', 'teaser', etc.
@@ -29,7 +29,7 @@
     'vocabulary-' ~ term.bundle|clean_class,
   ]
 %}
-<div{{ attributes.setAttribute('id', 'taxonomy-term-' ~ term.id).addClass(classes) }}>
+<div{{ attributes.setAttribute('id', 'taxonomy-term-' ~ taxonomy_term.id).addClass(classes) }}>
   {{ title_prefix }}
   {% if not page %}
     <h2><a href="{{ url }}">{{ name }}</a></h2>
diff --git a/core/themes/stable/templates/content/taxonomy-term.html.twig b/core/themes/stable/templates/content/taxonomy-term.html.twig
index 78203d9..7ca20f9 100644
--- a/core/themes/stable/templates/content/taxonomy-term.html.twig
+++ b/core/themes/stable/templates/content/taxonomy-term.html.twig
@@ -15,7 +15,7 @@
  *   @endcode
  * - attributes: HTML attributes for the wrapper.
  * - page: Flag for the full page state.
- * - term: The taxonomy term entity, including:
+ * - taxonomy_term: The taxonomy term entity, including:
  *   - id: The ID of the taxonomy term.
  *   - bundle: Machine name of the current vocabulary.
  * - view_mode: View mode, e.g. 'full', 'teaser', etc.
