diff --git a/core/modules/layout/layout.admin.inc b/core/modules/layout/layout.admin.inc
deleted file mode 100644
index 797c4c7..0000000
--- a/core/modules/layout/layout.admin.inc
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-/**
- * @file
- * Administration functions for layouts.
- */
-
-/**
- * Page callback: Demonstrates a layout template.
- *
- * @param string $key
- *   The key of the page layout being requested.
- *
- * @return array
- *   An array as expected by drupal_render().
- *
- * @see layout_menu()
- */
-function layout_page_view($key) {
-  $layout = layout_manager()->getDefinition($key);
-  drupal_set_title(t('View template %name', array('%name' => $layout['title'])), PASS_THROUGH);
-
-  // Render the layout in an admin context with region demonstrations.
-  $instance = layout_manager()->createInstance($key, array());
-  $regions = $instance->getRegions();
-  foreach ($regions as $region => $info) {
-    $regions[$region] = '<div class="layout-region-demonstration">' . check_plain($info['label']) . '</div>';
-  }
-  $build['demonstration'] = array(
-    '#type' => 'markup',
-    '#markup' => $instance->renderLayout(TRUE, $regions),
-  );
-  $build['#attached']['css'][] = drupal_get_path('module', 'layout') . '/layout.admin.css';
-  return $build;
-}
diff --git a/core/modules/layout/layout.module b/core/modules/layout/layout.module
index 17acc6d..9c40b54 100644
--- a/core/modules/layout/layout.module
+++ b/core/modules/layout/layout.module
@@ -16,30 +16,12 @@ function layout_menu() {
   );
   $items['admin/structure/templates/manage/%'] = array(
     'title' => 'View template',
-    'page callback' => 'layout_page_view',
-    'page arguments' => array(4),
-    'access callback' => 'layout_user_access',
-    'access arguments' => array(4),
-    'file' => 'layout.admin.inc',
+    'route_name' => 'layout_page_view',
   );
   return $items;
 }
 
 /**
- * Access callback: Checks the existence of a layout.
- *
- * @param string $key
- *   The key of the page layout being requested.
- *
- * @return bool
- *   TRUE if the current user can access page layout menu items; FALSE
- *   otherwise.
- */
-function layout_user_access($key) {
-  return (user_access('administer layouts') && layout_manager()->getDefinition($key));
-}
-
-/**
  * Implements hook_permission().
  */
 function layout_permission() {
diff --git a/core/modules/layout/layout.routing.yml b/core/modules/layout/layout.routing.yml
index d1cd540..886fa75 100644
--- a/core/modules/layout/layout.routing.yml
+++ b/core/modules/layout/layout.routing.yml
@@ -4,3 +4,9 @@ layout_page_list:
     _content: '\Drupal\layout\Controller\LayoutController::layoutPageList'
   requirements:
     _permission: 'administer layouts'
+layout_page_view:
+  pattern: '/admin/structure/templates/manage/{key}'
+  defaults:
+    _content: '\Drupal\layout\Controller\LayoutController::layoutPageView'
+  requirements:
+    layout_user_access: 'TRUE'
diff --git a/core/modules/layout/layout.services.yml b/core/modules/layout/layout.services.yml
index d387b77..c882dd9 100644
--- a/core/modules/layout/layout.services.yml
+++ b/core/modules/layout/layout.services.yml
@@ -2,3 +2,8 @@ services:
   plugin.manager.layout:
     class: Drupal\layout\Plugin\Type\LayoutManager
     arguments: ['@container.namespaces']
+  access_check.layout:
+    class: Drupal\layout\Access\LayoutAccessCheck
+    arguments: ['@plugin.manager.layout']
+    tags:
+      - { name: access_check }
diff --git a/core/modules/layout/lib/Drupal/layout/Access/LayoutAccessCheck.php b/core/modules/layout/lib/Drupal/layout/Access/LayoutAccessCheck.php
new file mode 100644
index 0000000..fbc055b
--- /dev/null
+++ b/core/modules/layout/lib/Drupal/layout/Access/LayoutAccessCheck.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\layout\Access\LayoutAccessCheck.
+ */
+
+namespace Drupal\layout\Access;
+
+use Drupal\Component\Plugin\PluginManagerInterface;
+use Drupal\Core\Access\AccessCheckInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Checks layout access.
+ */
+class LayoutAccessCheck implements AccessCheckInterface {
+
+  /**
+   * Constructs a LayoutAccessCheck object.
+   *
+   * @param \Drupal\Component\Plugin\PluginManagerInterface $layout_manager
+   *   The layout manager.
+   */
+  public function __construct(PluginManagerInterface $layout_manager) {
+    $this->layoutManager = $layout_manager;
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Route $route) {
+    return array_key_exists('layout_user_access', $route->getRequirements());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(Route $route, Request $request) {
+    return user_access('administer layouts') && $this->layoutManager->getDefinition($request->attributes->get('key'));
+  }
+}
diff --git a/core/modules/layout/lib/Drupal/layout/Controller/LayoutController.php b/core/modules/layout/lib/Drupal/layout/Controller/LayoutController.php
index 848ec02..96da556 100644
--- a/core/modules/layout/lib/Drupal/layout/Controller/LayoutController.php
+++ b/core/modules/layout/lib/Drupal/layout/Controller/LayoutController.php
@@ -6,6 +6,7 @@
 
 namespace Drupal\layout\Controller;
 
+use Drupal\Component\Utility\String;
 use Drupal\Core\ControllerInterface;
 use Drupal\layout\Plugin\Type\LayoutManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -76,4 +77,35 @@ public function layoutPageList() {
     t('module');
     t('theme');
   }
+
+  /**
+   * Demonstrates a layout template.
+   *
+   * @param string $key
+   *   The key of the page layout being requested.
+   *
+   * @return array
+   *   An array as expected by drupal_render().
+   *
+   * @see layout_menu()
+   */
+  public function layoutPageView($key) {
+    $layout = $this->layoutManager->getDefinition($key);
+    drupal_set_title(t('View template %name', array('%name' => $layout['title'])), PASS_THROUGH);
+
+    // Render the layout in an admin context with region demonstrations.
+    $instance = $this->layoutManager->createInstance($key, array());
+    $regions = $instance->getRegions();
+    foreach ($regions as $region => $info) {
+      $regions[$region] = '<div class="layout-region-demonstration">' . String::checkPlain($info['label']) . '</div>';
+    }
+    $build['demonstration'] = array(
+      '#type' => 'markup',
+      '#markup' => $instance->renderLayout(TRUE, $regions),
+    );
+    // @todo Convert layout.admin.css to a library.
+    $build['#attached']['css'][] = drupal_get_path('module', 'layout') . '/layout.admin.css';
+    return $build;
+  }
+
 }
