diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 8bfb3a3..3883987 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -148,8 +148,6 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
     $this->moduleHandler()->alter('entity_view_mode', $view_mode, $entity, $context);
 
     $build = array(
-      '#theme' => $this->entityTypeId,
-      "#{$this->entityTypeId}" => $entity,
       '#view_mode' => $view_mode,
       // Collect cache defaults for this entity.
       '#cache' => array(
@@ -159,6 +157,22 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
       ),
     );
 
+    // Use the entity specific #theme key if a template exists for it.
+    if (\Drupal::service('theme.registry')->getRuntime()->has($this->entityTypeId)) {
+      $build['#theme'] = $this->entityTypeId;
+      $build["#{$this->entityTypeId}"] = $entity;
+    }
+    else {
+      // Otherwise use the generic entity theme hook.
+      $build['#theme'] = 'entity';
+      $build['#entity'] = $entity;
+
+      // For backwards compatibility for entity types that used this without a
+      // valid theme hook in the past and also to put the entity type into the
+      // old place.
+      $build["#{$this->entityTypeId}"] = $entity;
+    }
+
     // Cache the rendered output if permitted by the view mode and global entity
     // type configuration.
     if ($this->isViewModeCacheable($view_mode) && !$entity->isNew() && $entity->isDefaultRevision() && $this->entityType->isRenderCacheable()) {
diff --git a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php
index 6a12ee6..4d02e89 100644
--- a/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php
+++ b/core/modules/field/tests/src/Kernel/EntityReference/EntityReferenceFormatterTest.php
@@ -194,8 +194,10 @@ public function testEntityFormatter() {
               <div class="field__item"><p>Hello, world!</p></div>
           </div>
 ';
-    $renderer->renderRoot($build[0]);
-    $this->assertEqual($build[0]['#markup'], 'default | ' . $this->referencedEntity->label() . $expected_rendered_name_field_1 . $expected_rendered_body_field_1, sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
+    $markup = (string) $renderer->renderRoot($build[0]);
+    $this->assertContains('default | ' . $this->referencedEntity->label(), $markup, "The markup returned by the $formatter formatter is correct for an item with a saved entity.");
+    $this->assertContains($expected_rendered_name_field_1, $markup);
+    $this->assertContains($expected_rendered_body_field_1, $markup);
     $expected_cache_tags = Cache::mergeTags(\Drupal::entityManager()->getViewBuilder($this->entityType)->getCacheTags(), $this->referencedEntity->getCacheTags());
     $expected_cache_tags = Cache::mergeTags($expected_cache_tags, FilterFormat::load('full_html')->getCacheTags());
     $this->assertEqual($build[0]['#cache']['tags'], $expected_cache_tags, format_string('The @formatter formatter has the expected cache tags.', array('@formatter' => $formatter)));
@@ -211,8 +213,10 @@ public function testEntityFormatter() {
           </div>
 ';
 
-    $renderer->renderRoot($build[1]);
-    $this->assertEqual($build[1]['#markup'], 'default | ' . $this->unsavedReferencedEntity->label() . $expected_rendered_name_field_2 . $expected_rendered_body_field_2, sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
+    $markup = (string) $renderer->renderRoot($build[1]);
+    $this->assertContains('default | ' . $this->unsavedReferencedEntity->label(), $markup, "The markup returned by the $formatter formatter is correct for an item with a saved entity.");
+    $this->assertContains($expected_rendered_name_field_2, $markup);
+    $this->assertContains($expected_rendered_body_field_2, $markup);
   }
 
   /**
diff --git a/core/modules/field_ui/tests/src/FunctionalJavascript/EntityDisplayTest.php b/core/modules/field_ui/tests/src/FunctionalJavascript/EntityDisplayTest.php
index 7cde00c..6aa96de 100644
--- a/core/modules/field_ui/tests/src/FunctionalJavascript/EntityDisplayTest.php
+++ b/core/modules/field_ui/tests/src/FunctionalJavascript/EntityDisplayTest.php
@@ -74,7 +74,7 @@ public function testEntityView() {
     $this->assertSession()->elementNotExists('css', '.field--name-field-test-text');
 
     $this->drupalGet('entity_test/structure/entity_test/display');
-    $this->assertSession()->elementExists('css', '.region-content-message.region-empty');
+    $this->assertSession()->elementExists('css', '.region-content-message.region-populated');
     $this->assertTrue($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
     $this->assertTrue($this->assertSession()->optionExists('fields[field_test_text][type]', 'hidden')->isSelected());
 
diff --git a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
index d9f36ff..dc18702 100644
--- a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\system\Tests\Entity;
 
+use Drupal\Component\Serialization\Yaml;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\simpletest\WebTestBase;
 
@@ -54,6 +55,9 @@ function testEntityViewController() {
       $this->assertRaw($get_label_markup($entity->label()));
       $this->assertRaw('full');
 
+      // Verify that the <h2> label is hidden for the full view mode.
+      $this->assertNoRaw('<h2');
+
       $this->drupalGet('entity_test_converter/' . $entity->id());
       $this->assertRaw($entity->label());
       $this->assertRaw('full');
@@ -61,6 +65,13 @@ function testEntityViewController() {
       $this->drupalGet('entity_test_no_view_mode/' . $entity->id());
       $this->assertRaw($entity->label());
       $this->assertRaw('full');
+
+      $this->drupalGet('entity_test/' . $entity->id() . '/test');
+      $this->assertRaw($entity->label());
+      $this->assertRaw('test');
+
+      // Verify that the <h2> label is shown for the full view mode.
+      $this->assertRaw('<h2');
     }
 
     // Test viewing a revisionable entity.
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 1f553da..18160ef 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -17,6 +17,7 @@
 use Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory;
 use Drupal\Core\PageCache\RequestPolicyInterface;
 use Drupal\Core\PhpStorage\PhpStorageFactory;
+use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Routing\StackedRouteMatchInterface;
 use Drupal\Core\Language\LanguageInterface;
@@ -217,6 +218,9 @@ function system_theme() {
       'variables' => array('menu_items' => NULL),
       'file' => 'system.admin.inc',
     ),
+    'entity' => array(
+      'render element' => 'elements',
+    ),
     'entity_add_list' => array(
       'variables' => array(
         'bundles' => array(),
@@ -248,6 +252,60 @@ function system_hook_info() {
 }
 
 /**
+ * Prepares variables for entity templates.
+ *
+ * Default template: entity.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - elements: An array of elements to display in view mode.
+ */
+function template_preprocess_entity(&$variables) {
+  $variables['view_mode'] = $variables['elements']['#view_mode'];
+  $variables['entity'] = $variables['elements']['#entity'];
+  /** @var \Drupal\Core\Entity\EntityInterface $entity */
+  $entity = $variables['entity'];
+
+  if (!$entity->isNew()) {
+    $variables['url'] = $entity->toUrl('canonical', array('language' => $entity->language()))->toString();
+  }
+
+  // If an element for the entity label is provided, put it into the label
+  // to make it accessible in a common way.
+  $title_key = $entity->getEntityType()->getKey('label');
+  if ($title_key && isset($variables['elements'][$title_key])) {
+    $variables['label'] = $variables['elements'][$title_key];
+    unset($variables['elements'][$title_key]);
+  }
+
+  // Helpful $content variable for templates.
+  $variables += array('content' => array());
+  foreach (Element::children($variables['elements']) as $key) {
+    $variables['content'][$key] = $variables['elements'][$key];
+  }
+}
+
+/**
+ * Implements hook_theme_suggestions_HOOK().
+ */
+function system_theme_suggestions_entity(array $variables) {
+  $suggestions = array();
+  /** @var \Drupal\Core\Entity\EntityInterface $entity */
+  $entity = $variables['elements']['#entity'];
+  $entity_type_id = $entity->getEntityTypeId();
+  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
+
+  $suggestions[] = 'entity__' . $entity_type_id;
+  $suggestions[] = 'entity__' . $entity_type_id . '__' . $sanitized_view_mode;
+  if ($entity->getEntityType()->hasKey('bundle')) {
+    $suggestions[] = 'entity__' . $entity_type_id . '__' . $entity->bundle();
+    $suggestions[] = 'entity__' . $entity_type_id . '__' . $entity->bundle() . '__' . $sanitized_view_mode;
+  }
+
+  return $suggestions;
+}
+
+/**
  * Implements hook_theme_suggestions_HOOK().
  */
 function system_theme_suggestions_html(array $variables) {
diff --git a/core/modules/system/templates/entity.html.twig b/core/modules/system/templates/entity.html.twig
new file mode 100644
index 0000000..bb87837
--- /dev/null
+++ b/core/modules/system/templates/entity.html.twig
@@ -0,0 +1,56 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display an entity.
+ *
+ * Available variables:
+ * - entity: The entity with limited access to object properties and methods.
+ *   Only method names starting with "get", "has", or "is" and a few common
+ *   methods such as "id", "label", and "bundle" are available. For example:
+ *   - entity.getEntityTypeId() will return the entity type ID.
+ *   - entity.hasField('field_example') returns TRUE if the entity includes
+ *     field_example. (This does not indicate the presence of a value in this
+ *     field.)
+ *   Calling other methods, such as entity.delete(), will result in an exception.
+ *   See \Drupal\Core\Entity\EntityInterface for a full list of methods.
+ * - label: The label of the entity.
+ * - content: All rendered field items. Use {{ content }} to print them all,
+ *   or print a subset such as {{ content.field_example }}. Use
+ *   {{ content|without('field_example') }} to temporarily suppress the printing
+ *   of a given child element.
+ * - url: Direct URL of the current entity.
+ * - attributes: HTML attributes for the containing element.
+ * - title_attributes: Same as attributes, except applied to the main title
+ *   tag that appears in the template.
+ * - content_attributes: Same as attributes, except applied to the main
+ *   content tag that appears in the template.
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ * - view_mode: View mode; for example, "teaser" or "full".
+ *
+ * @see template_preprocess_entity()
+ *
+ * @ingroup themeable
+ */
+#}
+<article{{ attributes }}>
+
+  {#
+  In the full view mode the entity label is assumed to be displayed as the page
+  title, so we do not display it here.
+  #}
+  {% if label and view_mode != "full" %}
+    {{ title_prefix }}
+    <h2{{ title_attributes }}>
+      {{ label }}
+    </h2>
+    {{ title_suffix }}
+  {% endif %}
+
+  <div{{ content_attributes }}>
+    {{ content }}
+  </div>
+
+</article>
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
index 5b6d37b..0f4beee 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
+++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
@@ -24,6 +24,13 @@ entity.entity_test.render_no_view_mode:
   requirements:
     _access: 'TRUE'
 
+entity.entity_test.canonical_test:
+  path: '/entity_test/{entity_test}/test'
+  defaults:
+    _entity_view: 'entity_test.test'
+  requirements:
+    _entity_access: 'entity_test.view'
+
 entity.entity_test.collection_referencing_entities:
   path: '/entity_test/list/{entity_reference_field_name}/{referenced_entity_type}/{referenced_entity_id}'
   defaults:
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
index a603f53..f2521e3 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
@@ -77,6 +77,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
         'type' => 'string',
         'weight' => -5,
       ))
+      ->setDisplayConfigurable('view', TRUE)
       ->setDisplayOptions('form', array(
         'type' => 'string_textfield',
         'weight' => -5,
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php
index 90eaf30..061dfaf 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php
@@ -15,15 +15,6 @@ class EntityTestViewBuilder extends EntityViewBuilder {
   /**
    * {@inheritdoc}
    */
-  protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
-    $build = parent::getBuildDefaults($entity, $view_mode);
-    unset($build['#theme']);
-    return $build;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function buildComponents(array &$build, array $entities, array $displays, $view_mode) {
     parent::buildComponents($build, $entities, $displays, $view_mode);
 
diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php
index ebf9e05..994bbfc 100644
--- a/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php
@@ -130,23 +130,23 @@ public function doTestRender($entities) {
     $footer_xpath = '//div[@class = "' . $view_class . '"]/footer[1]';
 
     $result = $this->xpath($header_xpath);
-    $this->assertTrue(strpos(trim((string) $result[0]), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
-    $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
 
     $result = $this->xpath($footer_xpath);
-    $this->assertTrue(strpos(trim((string) $result[0]), $entities[1]->label()) !== FALSE, 'The rendered entity appears in the footer of the view.');
-    $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), $entities[1]->label()) !== FALSE, 'The rendered entity appears in the footer of the view.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
 
     $preview = $view->preview('default', array($entities[1]->id()));
     $this->setRawContent($renderer->renderRoot($preview));
 
     $result = $this->xpath($header_xpath);
-    $this->assertTrue(strpos(trim((string) $result[0]), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
-    $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
 
     $result = $this->xpath($footer_xpath);
-    $this->assertTrue(strpos(trim((string) $result[0]), $entities[1]->label()) !== FALSE, 'The rendered entity appears in the footer of the view.');
-    $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), $entities[1]->label()) !== FALSE, 'The rendered entity appears in the footer of the view.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.');
 
     // Mark entity_test test view_mode as customizable.
     $entity_view_mode = \Drupal::entityManager()->getStorage('entity_view_mode')->load('entity_test.test');
@@ -163,8 +163,8 @@ public function doTestRender($entities) {
     $this->setRawContent($renderer->renderRoot($preview));
     $view_class = 'js-view-dom-id-' . $view->dom_id;
     $result = $this->xpath('//div[@class = "' . $view_class . '"]/header[1]');
-    $this->assertTrue(strpos(trim((string) $result[0]), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
-    $this->assertTrue(strpos(trim((string) $result[0]), 'test') !== FALSE, 'The rendered entity appeared in the right view mode.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
+    $this->assertTrue(strpos(trim($result[0]->asXML()), 'test') !== FALSE, 'The rendered entity appeared in the right view mode.');
 
     // Test entity access.
     $view = Views::getView('test_entity_area');
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php
index b247662..38b0a9e 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php
@@ -662,7 +662,7 @@ protected function doTestLanguageFallback($entity_type) {
     $controller = $this->entityManager->getViewBuilder($entity_type);
     $build = $controller->view($entity);
     $renderer->renderRoot($build);
-    $this->assertEqual($build['label']['#markup'], $values[$current_langcode]['name'], 'By default the entity is rendered in the current language.');
+    $this->assertEqual($build['label']['#plain_text'], $values[$current_langcode]['name'], 'By default the entity is rendered in the current language.');
 
     $langcodes = array_combine($this->langcodes, $this->langcodes);
     // We have no translation for the $langcode2 language, hence the expected
@@ -674,7 +674,7 @@ protected function doTestLanguageFallback($entity_type) {
       // making the renderable array keys available to compare.
       unset($build['#cache']);
       $renderer->renderRoot($build);
-      $this->assertEqual($build['label']['#markup'], $values[$expected]['name'], 'The entity is rendered in the expected language.');
+      $this->assertEqual($build['label']['#plain_text'], $values[$expected]['name'], 'The entity is rendered in the expected language.');
     }
   }
 
diff --git a/core/themes/classy/templates/content/entity.html.twig b/core/themes/classy/templates/content/entity.html.twig
new file mode 100644
index 0000000..a137caa
--- /dev/null
+++ b/core/themes/classy/templates/content/entity.html.twig
@@ -0,0 +1,46 @@
+{% extends "@stable/content/entity.html.twig" %}
+{#
+/**
+ * @file
+ * Default theme implementation to display an entity.
+ *
+ * Available variables:
+ * - entity: The entity with limited access to object properties and methods.
+ *   Only method names starting with "get", "has", or "is" and a few common
+ *   methods such as "id", "label", and "bundle" are available. For example:
+ *   - entity.getEntityTypeId() will return the entity type ID.
+ *   - entity.hasField('field_example') returns TRUE if the entity includes
+ *     field_example. (This does not indicate the presence of a value in this
+ *     field.)
+ *   Calling other methods, such as entity.delete(), will result in an exception.
+ *   See \Drupal\Core\Entity\EntityInterface for a full list of methods.
+ * - label: The title of the entity.
+ * - content: All rendered field items. Use {{ content }} to print them all,
+ *   or print a subset such as {{ content.field_example }}. Use
+ *   {{ content|without('field_example') }} to temporarily suppress the printing
+ *   of a given child element.
+ * - url: Direct URL of the current entity.
+ * - attributes: HTML attributes for the containing element.
+ * - title_attributes: Same as attributes, except applied to the main title
+ *   tag that appears in the template.
+ * - content_attributes: Same as attributes, except applied to the main
+ *   content tag that appears in the template.
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ * - view_mode: View mode; for example, "teaser" or "full".
+ *
+ * @see template_preprocess_entity()
+ *
+ * @ingroup themeable
+ */
+#}
+{%
+set classes = [
+  entity.getEntityTypeId(),
+  entity.getEntityType().getKey('bundle') ? entity.getEntityTypeId() ~ '--type-' ~ entity.bundle|clean_class,
+  view_mode ? entity.getEntityTypeId() ~ '--view-mode-' ~ view_mode|clean_class,
+]
+%}
+{% set attributes = attributes.addClass(classes) %}
diff --git a/core/themes/stable/templates/content/entity.html.twig b/core/themes/stable/templates/content/entity.html.twig
new file mode 100644
index 0000000..0db7c8a
--- /dev/null
+++ b/core/themes/stable/templates/content/entity.html.twig
@@ -0,0 +1,52 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display an entity.
+ *
+ * Available variables:
+ * - entity: The entity with limited access to object properties and methods.
+ *   Only method names starting with "get", "has", or "is" and a few common
+ *   methods such as "id", "label", and "bundle" are available. For example:
+ *   - entity.getEntityTypeId() will return the entity type ID.
+ *   - entity.hasField('field_example') returns TRUE if the entity includes
+ *     field_example. (This does not indicate the presence of a value in this
+ *     field.)
+ *   Calling other methods, such as entity.delete(), will result in an exception.
+ *   See \Drupal\Core\Entity\EntityInterface for a full list of methods.
+ * - label: The title of the entity.
+ * - content: All rendered field items. Use {{ content }} to print them all,
+ *   or print a subset such as {{ content.field_example }}. Use
+ *   {{ content|without('field_example') }} to temporarily suppress the printing
+ *   of a given child element.
+ * - url: Direct URL of the current entity.
+ * - attributes: HTML attributes for the containing element.
+ * - title_attributes: Same as attributes, except applied to the main title
+ *   tag that appears in the template.
+ * - content_attributes: Same as attributes, except applied to the main
+ *   content tag that appears in the template.
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ * - view_mode: View mode; for example, "teaser" or "full".
+ *
+ * @see template_preprocess_entity()
+ *
+ * @ingroup themeable
+ */
+#}
+<article{{ attributes }}>
+
+  {% if label and view_mode != "full" %}
+    {{ title_prefix }}
+    <h2{{ title_attributes }}>
+      {{ label }}
+    </h2>
+    {{ title_suffix }}
+  {% endif %}
+
+  <div{{ content_attributes }}>
+    {{ content }}
+  </div>
+
+</article>
