diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index d578499..23aba4f 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -130,8 +130,8 @@ function menu_local_tasks($level = 0) {
     if (!\Drupal::request()->attributes->has('exception') && !empty($route_name)) {
       $manager = \Drupal::service('plugin.manager.menu.local_task');
       $local_tasks = $manager->getTasksBuild($route_name);
-      foreach ($local_tasks as $level => $items) {
-        $data['tabs'][$level] = empty($data['tabs'][$level]) ? $items : array_merge($data['tabs'][$level], $items);
+      foreach ($local_tasks as $tab_level => $items) {
+        $data['tabs'][$tab_level] = empty($data['tabs'][$tab_level]) ? $items : array_merge($data['tabs'][$tab_level], $items);
       }
     }
 
@@ -177,16 +177,6 @@ function menu_secondary_local_tasks() {
 }
 
 /**
- * Returns the rendered local actions at the current level.
- */
-function menu_get_local_actions() {
-  $links = menu_local_tasks();
-  $route_name = Drupal::routeMatch()->getRouteName();
-  $manager = \Drupal::service('plugin.manager.menu.local_action');
-  return $manager->getActionsForRoute($route_name) + $links['actions'];
-}
-
-/**
  * Returns the router path, or the path for a default local task's parent.
  */
 function menu_tab_root_path() {
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 5d645e2..dd2d05d 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1384,14 +1384,6 @@ function template_preprocess_page(&$variables) {
     $variables['is_front'] = FALSE;
     $variables['db_is_active'] = FALSE;
   }
-  if (!defined('MAINTENANCE_MODE')) {
-    $variables['action_links']   = menu_get_local_actions();
-    $variables['tabs']           = menu_local_tabs();
-  }
-  else {
-    $variables['action_links']   = array();
-    $variables['tabs']           = array();
-  }
 
   if ($node = \Drupal::routeMatch()->getParameter('node')) {
     $variables['node'] = $node;
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index f53bb0c..d234a7e 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -269,6 +269,8 @@ public function rebuildThemeData() {
         'page_top' => 'Page top',
         'page_bottom' => 'Page bottom',
         'breadcrumb' => 'Breadcrumb',
+        'tabs' => 'Page tabs',
+        'actions' => 'Page actions',
       ),
       'description' => '',
       'features' => $this->defaultFeatures,
diff --git a/core/lib/Drupal/Core/Menu/LocalActionManager.php b/core/lib/Drupal/Core/Menu/LocalActionManager.php
index 208075c..d2cf376 100644
--- a/core/lib/Drupal/Core/Menu/LocalActionManager.php
+++ b/core/lib/Drupal/Core/Menu/LocalActionManager.php
@@ -181,10 +181,11 @@ public function getActionsForRoute($route_appears) {
           'url' => Url::fromRoute($route_name, $route_parameters),
           'localized_options' => $plugin->getOptions($this->routeMatch),
         ),
-        '#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account),
+        '#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account, TRUE),
         '#weight' => $plugin->getWeight(),
       );
     }
+
     return $links;
   }
 
diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php
index 86136d0..54e95c4 100644
--- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php
+++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php
@@ -293,8 +293,8 @@ public function getTasksBuild($current_route_name) {
         $route_parameters = $child->getRouteParameters($this->routeMatch);
 
         // Find out whether the user has access to the task.
-        $access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account);
-        if ($access) {
+        $access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account, TRUE);
+        if ($access->isAllowed()) {
           $active = $this->isRouteActive($current_route_name, $route_name, $route_parameters);
 
           // The plugin may have been set active in getLocalTasksForRoute() if
@@ -317,6 +317,7 @@ public function getTasksBuild($current_route_name) {
         }
       }
     }
+
     return $build;
   }
 
diff --git a/core/modules/block_content/src/Tests/BlockContentTestBase.php b/core/modules/block_content/src/Tests/BlockContentTestBase.php
index 82139c0..900c90a 100644
--- a/core/modules/block_content/src/Tests/BlockContentTestBase.php
+++ b/core/modules/block_content/src/Tests/BlockContentTestBase.php
@@ -60,6 +60,7 @@ protected function setUp() {
     }
 
     $this->adminUser = $this->drupalCreateUser($this->permissions);
+    $this->drupalPlaceBlock('system_page_actions_block');
   }
 
   /**
diff --git a/core/modules/field_ui/src/Tests/EntityDisplayModeTest.php b/core/modules/field_ui/src/Tests/EntityDisplayModeTest.php
index 7b7fe12..5f497a8 100644
--- a/core/modules/field_ui/src/Tests/EntityDisplayModeTest.php
+++ b/core/modules/field_ui/src/Tests/EntityDisplayModeTest.php
@@ -19,9 +19,18 @@ class EntityDisplayModeTest extends WebTestBase {
   /**
    * Modules to enable.
    *
-   * @var array
+   * @var string[]
    */
-  public static $modules = array('entity_test', 'field_ui');
+  public static $modules = ['block', 'entity_test', 'field_ui'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_actions_block');
+  }
 
   /**
    * Tests the EntityViewMode user interface.
diff --git a/core/modules/field_ui/src/Tests/FieldUIRouteTest.php b/core/modules/field_ui/src/Tests/FieldUIRouteTest.php
index 332a87d..9f44c86 100644
--- a/core/modules/field_ui/src/Tests/FieldUIRouteTest.php
+++ b/core/modules/field_ui/src/Tests/FieldUIRouteTest.php
@@ -23,7 +23,7 @@ class FieldUIRouteTest extends WebTestBase {
    *
    * @var string[]
    */
-  public static $modules = array('entity_test', 'field_ui');
+  public static $modules = ['block', 'entity_test', 'field_ui'];
 
   /**
    * {@inheritdoc}
@@ -32,6 +32,7 @@ protected function setUp() {
     parent::setUp();
 
     $this->drupalLogin($this->rootUser);
+    $this->drupalPlaceBlock('system_page_tabs_block');
   }
 
   /**
diff --git a/core/modules/field_ui/src/Tests/ManageFieldsTest.php b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
index 3b90bff..1d18de2 100644
--- a/core/modules/field_ui/src/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php
@@ -66,7 +66,10 @@ class ManageFieldsTest extends WebTestBase {
    */
   protected function setUp() {
     parent::setUp();
+
     $this->drupalPlaceBlock('system_breadcrumb_block');
+    $this->drupalPlaceBlock('system_page_actions_block');
+    $this->drupalPlaceBlock('system_page_tabs_block');
 
     // Create a test user.
     $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'administer taxonomy', 'administer taxonomy_term fields', 'administer taxonomy_term display', 'administer users', 'administer account settings', 'administer user display', 'bypass node access'));
diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php
index 9440179..cb591a4 100644
--- a/core/modules/forum/src/Tests/ForumTest.php
+++ b/core/modules/forum/src/Tests/ForumTest.php
@@ -113,6 +113,7 @@ protected function setUp() {
       'access comments',
     ));
     $this->drupalPlaceBlock('help_block', array('region' => 'help'));
+    $this->drupalPlaceBlock('system_page_actions_block');
   }
 
   /**
diff --git a/core/modules/language/src/Tests/LanguageTourTest.php b/core/modules/language/src/Tests/LanguageTourTest.php
index 98418b6..03d2b16 100644
--- a/core/modules/language/src/Tests/LanguageTourTest.php
+++ b/core/modules/language/src/Tests/LanguageTourTest.php
@@ -28,7 +28,7 @@ class LanguageTourTest extends TourTestBase {
    *
    * @var array
    */
-  public static $modules = array('language', 'tour');
+  public static $modules = ['block', 'language', 'tour'];
 
   /**
    * {@inheritdoc}
@@ -37,6 +37,7 @@ protected function setUp() {
     parent::setUp();
     $this->adminUser = $this->drupalCreateUser(array('administer languages', 'access tour'));
     $this->drupalLogin($this->adminUser);
+    $this->drupalPlaceBlock('system_page_actions_block');
   }
 
   /**
diff --git a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php b/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
index db98745..0e1c33c 100644
--- a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
@@ -18,6 +18,22 @@
 class ShortcutSetsTest extends ShortcutTestBase {
 
   /**
+   * Modules to enable.
+   *
+   * @var string[]
+   */
+  public static $modules = ['block'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_actions_block');
+  }
+
+  /**
    * Tests creating a shortcut set.
    */
   function testShortcutSetAdd() {
diff --git a/core/modules/simpletest/src/Tests/BrowserTest.php b/core/modules/simpletest/src/Tests/BrowserTest.php
index d43f63b..ecf9a28 100644
--- a/core/modules/simpletest/src/Tests/BrowserTest.php
+++ b/core/modules/simpletest/src/Tests/BrowserTest.php
@@ -24,6 +24,22 @@ class BrowserTest extends WebTestBase {
   protected static $cookieSet = FALSE;
 
   /**
+   * Modules to enable.
+   *
+   * @var string[]
+   */
+  public static $modules = ['block'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_tabs_block');
+  }
+
+  /**
    * Test \Drupal\simpletest\WebTestBase::getAbsoluteUrl().
    */
   function testGetAbsoluteUrl() {
diff --git a/core/modules/system/src/Plugin/Block/SystemPageActionsBlock.php b/core/modules/system/src/Plugin/Block/SystemPageActionsBlock.php
new file mode 100644
index 0000000..493257b
--- /dev/null
+++ b/core/modules/system/src/Plugin/Block/SystemPageActionsBlock.php
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Plugin\Block\SystemPageActionsBlock.
+ */
+
+namespace Drupal\system\Plugin\Block;
+
+use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Menu\LocalActionManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Provides a block to display the page actions.
+ *
+ * @Block(
+ *   id = "system_page_actions_block",
+ *   admin_label = @Translation("Page actions")
+ * )
+ */
+class SystemPageActionsBlock extends BlockBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The configuration factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The local action manger.
+   *
+   * @var \Drupal\Core\Menu\LocalActionManagerInterface
+   */
+  protected $localActionManager;
+
+  /**
+   * A request stack object.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * Creates a SystemPageActionsBlock instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   * @param \Drupal\Core\Menu\LocalActionManagerInterface $local_action_manager
+   *   A local action manager.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack object.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, LocalActionManagerInterface $local_action_manager, RequestStack $request_stack) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->configFactory = $config_factory;
+    $this->localActionManager = $local_action_manager;
+    $this->requestStack = $request_stack;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('plugin.manager.menu.local_action'),
+      $container->get('request_stack')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return ['label_display' => FALSE];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    $build = [];
+    $links = menu_local_tasks();
+    $request = $this->requestStack->getCurrentRequest();
+    $route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME);
+    $action_links = $this->localActionManager->getActionsForRoute($route_name) + $links['actions'];
+    if (empty($action_links)) {
+      return [];
+    }
+
+    $build['action_links'] = $action_links;
+
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
+    // The "Page actions" block is never cacheable, due to access checking.
+    $form['cache']['#disabled'] = TRUE;
+    $form['cache']['#description'] = $this->t('This block is never cacheable because access checking is needed, it is not configurable.');
+    $form['cache']['max_age']['#value'] = 0;
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    // @todo Make me cacheable now that https://drupal.org/node/2287071 has landed.
+    return 0;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return ['route.name'];
+  }
+
+}
diff --git a/core/modules/system/src/Plugin/Block/SystemPageTabsBlock.php b/core/modules/system/src/Plugin/Block/SystemPageTabsBlock.php
new file mode 100644
index 0000000..83cc0dc
--- /dev/null
+++ b/core/modules/system/src/Plugin/Block/SystemPageTabsBlock.php
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Plugin\Block\SystemPageTabsBlock.
+ */
+
+namespace Drupal\system\Plugin\Block;
+
+use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a block to display the page tabs.
+ *
+ * @Block(
+ *   id = "system_page_tabs_block",
+ *   admin_label = @Translation("Page tabs")
+ * )
+ */
+class SystemPageTabsBlock extends BlockBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The configuration factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Creates a SystemPageTabsBlock instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return ['label_display' => FALSE];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    $tabs = menu_local_tabs();
+    if (empty($tabs)) {
+      return [];
+    }
+    $build['tabs'] = $tabs;
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
+    // The "Page tabs" block is never cacheable, due to access checking.
+    $form['cache']['#disabled'] = TRUE;
+    $form['cache']['#description'] = $this->t('This block is never cacheable because access checking is needed, it is not configurable.');
+    $form['cache']['max_age']['#value'] = 0;
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    // @todo Make cacheable now that https://drupal.org/node/2287071 has landed.
+    return 0;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return ['route.name'];
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Menu/LocalActionTest.php b/core/modules/system/src/Tests/Menu/LocalActionTest.php
index c049198..7fd2f2f 100644
--- a/core/modules/system/src/Tests/Menu/LocalActionTest.php
+++ b/core/modules/system/src/Tests/Menu/LocalActionTest.php
@@ -18,9 +18,20 @@
 class LocalActionTest extends WebTestBase {
 
   /**
+   * Modules to enable.
+   *
+   * @var string[]
+   */
+  public static $modules = ['block', 'menu_test'];
+
+  /**
    * {@inheritdoc}
    */
-  public static $modules = array('menu_test');
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_actions_block');
+  }
 
   /**
    * Tests appearance of local actions.
diff --git a/core/modules/system/src/Tests/Menu/LocalTasksTest.php b/core/modules/system/src/Tests/Menu/LocalTasksTest.php
index b7824ef..4f99b86 100644
--- a/core/modules/system/src/Tests/Menu/LocalTasksTest.php
+++ b/core/modules/system/src/Tests/Menu/LocalTasksTest.php
@@ -17,7 +17,21 @@
  */
 class LocalTasksTest extends WebTestBase {
 
-  public static $modules = array('menu_test', 'entity_test');
+  /**
+   * Modules to enable.
+   *
+   * @var string[]
+   */
+  public static $modules = ['block', 'menu_test', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_tabs_block');
+  }
 
   /**
    * Asserts local tasks in the page output.
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 96f0083..99785f9 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -169,6 +169,14 @@ function system_theme() {
     'block__system_messages_block' => array(
       'base hook' => 'block',
     ),
+    'block__system_page_actions_block' => [
+      'base hook' => 'block',
+      'template' => 'block--system-page-actions-block',
+    ],
+    'block__system_page_tabs_block' => [
+      'base hook' => 'block',
+      'template' => 'block--system-page-tabs-block',
+    ],
     'block__system_menu_block' => array(
       'render element' => 'elements',
       'base hook' => 'block',
@@ -782,6 +790,14 @@ function system_preprocess_block(&$variables) {
       }
       break;
 
+    case 'system_page_actions_block':
+      $variables['action_links'] = $variables['content']['action_links'];
+      break;
+
+    case 'system_page_tabs_block':
+      $variables['tabs'] = $variables['content']['tabs'];
+      break;
+
     case 'system_powered_by_block':
       $variables['attributes']['role'] = 'complementary';
       break;
diff --git a/core/modules/system/templates/block--system-page-actions-block.html.twig b/core/modules/system/templates/block--system-page-actions-block.html.twig
new file mode 100644
index 0000000..a5972dc
--- /dev/null
+++ b/core/modules/system/templates/block--system-page-actions-block.html.twig
@@ -0,0 +1,18 @@
+{% extends "@block/block.html.twig" %}
+{#
+/**
+ * @file
+ * Default theme implementation for page local actions.
+ *
+ * Available variables:
+ * - action_links: Actions local to the page, such as "Add menu" on the menu
+ *   administration interface.
+ *
+ * @ingroup themeable
+ */
+#}
+{% block content %}
+  {% if action_links %}
+    <nav class="action-links">{{ action_links }}</nav>
+  {% endif %}
+{% endblock %}
diff --git a/core/modules/system/templates/block--system-page-tabs-block.html.twig b/core/modules/system/templates/block--system-page-tabs-block.html.twig
new file mode 100644
index 0000000..780abe7
--- /dev/null
+++ b/core/modules/system/templates/block--system-page-tabs-block.html.twig
@@ -0,0 +1,16 @@
+{% extends "@block/block.html.twig" %}
+{#
+/**
+ * @file
+ * Default theme implementation for page tabs.
+ *
+ * Available variables:
+ * - tabs: The Tabs linking to any sub-pages beneath the current page (e.g., the
+ *   view and edit tabs when displaying a node).
+ *
+ * @ingroup themeable
+ */
+#}
+{% block content %}
+  {{ tabs }}
+{% endblock %}
diff --git a/core/modules/system/templates/page.html.twig b/core/modules/system/templates/page.html.twig
index c5a3711..6200539 100644
--- a/core/modules/system/templates/page.html.twig
+++ b/core/modules/system/templates/page.html.twig
@@ -32,10 +32,6 @@
  * - title_suffix: Additional output populated by modules, intended to be
  *   displayed after the main title tag that appears in the template.
  * - messages: Status and error messages. Should be displayed prominently.
- * - tabs: Tabs linking to any sub-pages beneath the current page (e.g., the
- *   view and edit tabs when displaying a node).
- * - action_links: Actions local to the page, such as "Add menu" on the menu
- *   administration interface.
  * - node: Fully loaded node, if there is an automatically-loaded node
  *   associated with the page and the node ID is the second argument in the
  *   page's path (e.g. node/12345 and node/12345/revisions, but not
@@ -52,6 +48,8 @@
  * - page.sidebar_second: Items for the second sidebar.
  * - page.footer: Items for the footer region.
  * - page.breadcrumb: Items for the breadcrumb region.
+ * - page.tabs: Items for the tabs region.
+ * - page.actions: Items for the actions region.
  *
  * @see template_preprocess_page()
  * @see html.html.twig
@@ -111,11 +109,9 @@
       {% endif %}
       {{ title_suffix }}
 
-      {{ tabs }}
+      {{ page.tabs }}
 
-      {% if action_links %}
-        <nav class="action-links">{{ action_links }}</nav>
-      {% endif %}
+      {{ page.actions }}
 
       {{ page.content }}
     </div>{# /.layout-content #}
diff --git a/core/modules/taxonomy/src/Tests/TermTest.php b/core/modules/taxonomy/src/Tests/TermTest.php
index bfeeb86..e326c74 100644
--- a/core/modules/taxonomy/src/Tests/TermTest.php
+++ b/core/modules/taxonomy/src/Tests/TermTest.php
@@ -35,8 +35,22 @@ class TermTest extends TaxonomyTestBase {
    */
   protected $field;
 
+  /**
+   * Modules to enable.
+   *
+   * @var string[]
+   */
+  public static $modules = ['block'];
+
+  /**
+   * {@inheritdoc}
+   */
   protected function setUp() {
     parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_actions_block');
+    $this->drupalPlaceBlock('system_page_tabs_block');
+
     $this->drupalLogin($this->drupalCreateUser(['administer taxonomy', 'bypass node access']));
     $this->vocabulary = $this->createVocabulary();
 
diff --git a/core/modules/taxonomy/src/Tests/VocabularyUiTest.php b/core/modules/taxonomy/src/Tests/VocabularyUiTest.php
index 3a34c2e..b976091 100644
--- a/core/modules/taxonomy/src/Tests/VocabularyUiTest.php
+++ b/core/modules/taxonomy/src/Tests/VocabularyUiTest.php
@@ -24,7 +24,7 @@ class VocabularyUiTest extends TaxonomyTestBase {
    * @var \Drupal\taxonomy\VocabularyInterface
    */
   protected $vocabulary;
-
+ 
   protected function setUp() {
     parent::setUp();
     $this->drupalLogin($this->drupalCreateUser(['administer taxonomy']));
diff --git a/core/modules/tour/src/Tests/TourTest.php b/core/modules/tour/src/Tests/TourTest.php
index 8ed261c..fa3df85 100644
--- a/core/modules/tour/src/Tests/TourTest.php
+++ b/core/modules/tour/src/Tests/TourTest.php
@@ -21,7 +21,7 @@ class TourTest extends TourTestBasic {
    *
    * @var array
    */
-  public static $modules = array('tour', 'locale', 'language', 'tour_test');
+  public static $modules = ['block', 'tour', 'locale', 'language', 'tour_test'];
 
   /**
    * The permissions required for a logged in user to test tour tips.
@@ -42,6 +42,18 @@ class TourTest extends TourTestBasic {
   );
 
   /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalPlaceBlock('system_page_actions_block', [
+      'theme' => 'seven',
+      'region' => 'actions'
+    ]);
+  }
+
+  /**
    * Test tour functionality.
    */
   public function testTourFunctionality() {
diff --git a/core/modules/tracker/src/Tests/TrackerTest.php b/core/modules/tracker/src/Tests/TrackerTest.php
index c20c054..5c256d5 100644
--- a/core/modules/tracker/src/Tests/TrackerTest.php
+++ b/core/modules/tracker/src/Tests/TrackerTest.php
@@ -29,7 +29,7 @@ class TrackerTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('comment', 'tracker', 'history', 'node_test');
+  public static $modules = ['block', 'comment', 'tracker', 'history', 'node_test'];
 
   /**
    * The main user for testing.
@@ -54,6 +54,7 @@ protected function setUp() {
     $this->user = $this->drupalCreateUser($permissions);
     $this->otherUser = $this->drupalCreateUser($permissions);
     $this->addDefaultCommentField('node', 'page');
+    $this->drupalPlaceBlock('system_page_tabs_block');
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php b/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
index 31bfd3c..3b9f5bb 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
+++ b/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
@@ -33,10 +33,14 @@ class DisplayPageWebTest extends PluginTestBase {
    */
   public static $modules = ['menu_ui', 'block'];
 
+  /**
+   * {@inheritdoc}
+   */
   protected function setUp() {
     parent::setUp();
 
     $this->enableViewsTestModule();
+    $this->drupalPlaceBlock('system_page_tabs_block');
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Wizard/WizardTestBase.php b/core/modules/views/src/Tests/Wizard/WizardTestBase.php
index 0a2e998..b81ee73 100644
--- a/core/modules/views/src/Tests/Wizard/WizardTestBase.php
+++ b/core/modules/views/src/Tests/Wizard/WizardTestBase.php
@@ -27,6 +27,7 @@ protected function setUp() {
     // Create and log in a user with administer views permission.
     $views_admin = $this->drupalCreateUser(array('administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions'));
     $this->drupalLogin($views_admin);
+    $this->drupalPlaceBlock('system_page_actions_block');
   }
 
 }
diff --git a/core/profiles/minimal/config/install/block.block.stark_page_actions.yml b/core/profiles/minimal/config/install/block.block.stark_page_actions.yml
new file mode 100644
index 0000000..44cb317
--- /dev/null
+++ b/core/profiles/minimal/config/install/block.block.stark_page_actions.yml
@@ -0,0 +1,18 @@
+id: bartik_page_actions
+theme: stark
+weight: 10
+status: true
+langcode: en
+region: actions
+plugin: system_page_actions_block
+settings:
+  id: system_page_actions_block
+  label: Page actions
+  provider: system
+  label_display: '0'
+dependencies:
+  module:
+    - system
+  theme:
+    - stark
+visibility: {  }
diff --git a/core/profiles/minimal/config/install/block.block.stark_page_tabs.yml b/core/profiles/minimal/config/install/block.block.stark_page_tabs.yml
new file mode 100644
index 0000000..6660d0f
--- /dev/null
+++ b/core/profiles/minimal/config/install/block.block.stark_page_tabs.yml
@@ -0,0 +1,18 @@
+id: bartik_page_tabs
+theme: stark
+weight: 10
+status: true
+langcode: en
+region: tabs
+plugin: system_page_tabs_block
+settings:
+  id: system_page_tabs_block
+  label: Page tabs
+  provider: system
+  label_display: '0'
+dependencies:
+  module:
+    - system
+  theme:
+    - stark
+visibility: {  }
diff --git a/core/profiles/standard/config/install/block.block.bartik_page_actions.yml b/core/profiles/standard/config/install/block.block.bartik_page_actions.yml
new file mode 100644
index 0000000..4e051e8
--- /dev/null
+++ b/core/profiles/standard/config/install/block.block.bartik_page_actions.yml
@@ -0,0 +1,18 @@
+id: bartik_page_actions
+theme: bartik
+weight: 10
+status: true
+langcode: en
+region: actions
+plugin: system_page_actions_block
+settings:
+  id: system_page_actions_block
+  label: Page actions
+  provider: system
+  label_display: '0'
+dependencies:
+  module:
+    - system
+  theme:
+    - bartik
+visibility: {  }
diff --git a/core/profiles/standard/config/install/block.block.bartik_page_tabs.yml b/core/profiles/standard/config/install/block.block.bartik_page_tabs.yml
new file mode 100644
index 0000000..c8cf59a
--- /dev/null
+++ b/core/profiles/standard/config/install/block.block.bartik_page_tabs.yml
@@ -0,0 +1,18 @@
+id: bartik_page_tabs
+theme: bartik
+weight: 10
+status: true
+langcode: en
+region: tabs
+plugin: system_page_tabs_block
+settings:
+  id: system_page_tabs_block
+  label: Page tabs
+  provider: system
+  label_display: '0'
+dependencies:
+  module:
+    - system
+  theme:
+    - bartik
+visibility: {  }
diff --git a/core/profiles/standard/config/install/block.block.seven_page_actions.yml b/core/profiles/standard/config/install/block.block.seven_page_actions.yml
new file mode 100644
index 0000000..7802a57
--- /dev/null
+++ b/core/profiles/standard/config/install/block.block.seven_page_actions.yml
@@ -0,0 +1,18 @@
+id: page_actions
+theme: seven
+weight: 0
+status: true
+langcode: en
+region: actions
+plugin: system_page_actions_block
+settings:
+  id: system_page_actions_block
+  label: Page actions
+  provider: system
+  label_display: '0'
+dependencies:
+  module:
+    - system
+  theme:
+    - seven
+visibility: {  }
diff --git a/core/profiles/standard/config/install/block.block.seven_page_tabs.yml b/core/profiles/standard/config/install/block.block.seven_page_tabs.yml
new file mode 100644
index 0000000..9b9995a
--- /dev/null
+++ b/core/profiles/standard/config/install/block.block.seven_page_tabs.yml
@@ -0,0 +1,18 @@
+id: page_tabs
+theme: seven
+weight: 0
+status: true
+langcode: en
+region: tabs
+plugin: system_page_tabs_block
+settings:
+  id: system_page_tabs_block
+  label: Page tabs
+  provider: system
+  label_display: '0'
+dependencies:
+  module:
+    - system
+  theme:
+    - seven
+visibility: {  }
diff --git a/core/themes/bartik/bartik.info.yml b/core/themes/bartik/bartik.info.yml
index fb8f2fb..444992e 100644
--- a/core/themes/bartik/bartik.info.yml
+++ b/core/themes/bartik/bartik.info.yml
@@ -24,6 +24,8 @@ regions:
   highlighted: Highlighted
   featured_top: 'Featured top'
   breadcrumb: Breadcrumb
+  tabs: Tabs
+  actions: Actions
   content: Content
   sidebar_first: 'Sidebar first'
   sidebar_second: 'Sidebar second'
diff --git a/core/themes/bartik/templates/block--system-page-actions-block.html.twig b/core/themes/bartik/templates/block--system-page-actions-block.html.twig
new file mode 100644
index 0000000..b8283b5
--- /dev/null
+++ b/core/themes/bartik/templates/block--system-page-actions-block.html.twig
@@ -0,0 +1,20 @@
+{% extends "@block/block.html.twig" %}
+{#
+/**
+ * @file
+ * Bartik's theme implementation for page local actions.
+ *
+ * Available variables:
+ * - action_links: Actions local to the page, such as "Add menu" on the menu
+ *   administration interface.
+ *
+ * @ingroup themeable
+ */
+#}
+{% block content %}
+  {% if action_links %}
+    <ul class="action-links">
+      {{ action_links }}
+    </ul>
+  {% endif %}
+{% endblock %}
diff --git a/core/themes/bartik/templates/block--system-page-tabs-block.html.twig b/core/themes/bartik/templates/block--system-page-tabs-block.html.twig
new file mode 100644
index 0000000..429ad98
--- /dev/null
+++ b/core/themes/bartik/templates/block--system-page-tabs-block.html.twig
@@ -0,0 +1,20 @@
+{% extends "@block/block.html.twig" %}
+{#
+/**
+ * @file
+ * Bartik's theme implementation for page tabs.
+ *
+ * Available variables:
+ * - tabs: The Tabs linking to any sub-pages beneath the current page (e.g., the
+ *   view and edit tabs when displaying a node).
+ *
+ * @ingroup themeable
+ */
+#}
+{% block content %}
+  {% if tabs %}
+     <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
+       {{ tabs }}
+     </nav>
+  {% endif %}
+{% endblock %}
diff --git a/core/themes/bartik/templates/page.html.twig b/core/themes/bartik/templates/page.html.twig
index a3583fe..308dea7 100644
--- a/core/themes/bartik/templates/page.html.twig
+++ b/core/themes/bartik/templates/page.html.twig
@@ -38,10 +38,6 @@
  * - title: The page title, for use in the actual content.
  * - title_suffix: Additional output populated by modules, intended to be
  *   displayed after the main title tag that appears in the template.
- * - tabs: Tabs linking to any sub-pages beneath the current page (e.g., the
- *   view and edit tabs when displaying a node).
- * - action_links: Actions local to the page, such as "Add menu" on the menu
- *   administration interface.
  * - node: Fully loaded node, if there is an automatically-loaded node
  *   associated with the page and the node ID is the second argument in the
  *   page's path (e.g. node/12345 and node/12345/revisions, but not
@@ -66,6 +62,8 @@
  * - page.footer_fourth: Items for the fourth footer column.
  * - page.footer_fifth: Items for the fifth footer column.
  * - page.breadcrumb: Items for the breadcrumb region.
+ * - page.tabs: Items for the tabs region.
+ * - page.actions: Items for the actions region.
  *
  * @see template_preprocess_page()
  * @see bartik_preprocess_page()
@@ -136,15 +134,9 @@
               </h1>
             {% endif %}
             {{ title_suffix }}
-            {% if tabs %}
-              <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
-                {{ tabs }}
-              </nav>
-            {% endif %}
+            {{ page.tabs }}
             {{ page.help }}
-            {% if action_links %}
-              <ul class="action-links">{{ action_links }}</ul>
-            {% endif %}
+            {{ page.actions }}
             {{ page.content }}
           </section>
         </main>
diff --git a/core/themes/classy/templates/layout/page.html.twig b/core/themes/classy/templates/layout/page.html.twig
index 57533c8..b9c6c1b 100644
--- a/core/themes/classy/templates/layout/page.html.twig
+++ b/core/themes/classy/templates/layout/page.html.twig
@@ -31,10 +31,6 @@
  * - title: The page title, for use in the actual content.
  * - title_suffix: Additional output populated by modules, intended to be
  *   displayed after the main title tag that appears in the template.
- * - tabs: Tabs linking to any sub-pages beneath the current page (e.g., the
- *   view and edit tabs when displaying a node).
- * - action_links: Actions local to the page, such as "Add menu" on the menu
- *   administration interface.
  * - node: Fully loaded node, if there is an automatically-loaded node
  *   associated with the page and the node ID is the second argument in the
  *   page's path (e.g. node/12345 and node/12345/revisions, but not
@@ -52,6 +48,8 @@
  * - page.sidebar_second: Items for the second sidebar.
  * - page.footer: Items for the footer region.
  * - page.breadcrumb: Items for the breadcrumb region.
+ * - page.tabs: Items for the tabs region.
+ * - page.actions: Items for the actions region.
  *
  * @see template_preprocess_page()
  * @see html.html.twig
@@ -110,11 +108,9 @@
       {% endif %}
       {{ title_suffix }}
 
-      {{ tabs }}
+      {{ page.tabs }}
 
-      {% if action_links %}
-        <nav class="action-links">{{ action_links }}</nav>
-      {% endif %}
+      {{ page.actions }}
 
       {{ page.content }}
     </div>{# /.layout-content #}
diff --git a/core/themes/seven/seven.info.yml b/core/themes/seven/seven.info.yml
index 99a3ec1..781fa35 100644
--- a/core/themes/seven/seven.info.yml
+++ b/core/themes/seven/seven.info.yml
@@ -21,5 +21,7 @@ regions:
   page_bottom: 'Page bottom'
   sidebar_first: 'First sidebar'
   breadcrumb: Breadcrumb
+  tabs: Tabs
+  actions: Actions
 regions_hidden:
   - sidebar_first
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index b71e22c..67d6edc 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -25,18 +25,6 @@ function seven_preprocess_html(&$variables) {
 }
 
 /**
- * Implements hook_preprocess_HOOK() for page templates.
- */
-function seven_preprocess_page(&$variables) {
-  $variables['primary_local_tasks'] = $variables['tabs'];
-  unset($variables['primary_local_tasks']['#secondary']);
-  $variables['secondary_local_tasks'] = array(
-    '#theme' => 'menu_local_tasks',
-    '#secondary' => isset($variables['tabs']['#secondary']) ? $variables['tabs']['#secondary'] : '',
-  );
-}
-
-/**
  * Implements hook_pre_render_HOOK() for menu-local-tasks templates.
  *
  * Use preprocess hook to set #attached to child elements
diff --git a/core/themes/seven/templates/page.html.twig b/core/themes/seven/templates/page.html.twig
index 1c36be5..b863eff 100644
--- a/core/themes/seven/templates/page.html.twig
+++ b/core/themes/seven/templates/page.html.twig
@@ -32,10 +32,6 @@
  * - title: The page title, for use in the actual content.
  * - title_suffix: Additional output populated by modules, intended to be
  *   displayed after the main title tag that appears in the template.
- * - tabs: Tabs linking to any sub-pages beneath the current page (e.g., the
- *   view and edit tabs when displaying a node).
- * - action_links: Actions local to the page, such as "Add menu" on the menu
- *   administration interface.
  * - node: Fully loaded node, if there is an automatically-loaded node
  *   associated with the page and the node ID is the second argument in the
  *   page's path (e.g. node/12345 and node/12345/revisions, but not
@@ -50,6 +46,10 @@
  * - page.sidebar_second: Items for the second sidebar.
  * - page.page_bottom: Items for the footer region.
  * - page.breadcrumb: Items for the breadcrumb region.
+ * - tabs: Tabs linking to any sub-pages beneath the current page (e.g., the
+ *   view and edit tabs when displaying a node).
+ * - action_links: Actions local to the page, such as "Add menu" on the menu
+ *   administration interface.
  *
  * @see template_preprocess_page()
  * @see seven_preprocess_page()
@@ -63,19 +63,16 @@
         <h1 class="page-title">{{ title }}</h1>
       {% endif %}
       {{ title_suffix }}
-      {% if primary_local_tasks %}
-        {{ primary_local_tasks }}
+      {% if page.tabs %}
+        <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
+          {{ page.tabs }}
+        </nav>
       {% endif %}
     </div>
   </header>
 
   <div class="layout-container">
-    {% if secondary_local_tasks %}
-      <div class="tabs-secondary clearfix" role="navigation">{{ secondary_local_tasks }}</div>
-    {% endif %}
-
     {{ page.breadcrumb }}
-
     <main class="page-content clearfix" role="main">
       <div class="visually-hidden"><a id="main-content" tabindex="-1"></a></div>
       {{ page.highlighted }}
@@ -84,12 +81,11 @@
           {{ page.help }}
         </div>
       {% endif %}
-      {% if action_links %}
+      {% if page.actions %}
         <ul class="action-links">
-          {{ action_links }}
+          {{ page.actions }}
         </ul>
       {% endif %}
       {{ page.content }}
     </main>
-
   </div>
