diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
index e78b5bc..6831705 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
@@ -17,7 +17,7 @@ class NodeAccessBaseTableTest extends NodeTestBase {
    *
    * @var array
    */
-  public static $modules = array('node_access_test');
+  public static $modules = array('node_access_test', 'views');
 
   /**
    * The installation profile to use with this test.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index bf79da6..b350c5e 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1319,7 +1319,6 @@ function node_view_multiple($nodes, $view_mode = 'teaser', $langcode = NULL) {
  * default setting for number of posts to show on node listing pages.
  *
  * @see node_page_default()
- * @see taxonomy_term_page()
  * @see node_form_system_site_information_settings_form_submit()
  */
 function node_form_system_site_information_settings_form_alter(&$form, &$form_state, $form_id) {
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php b/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php
index c483d9e..d747ce2 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php
@@ -17,7 +17,7 @@ class PathTaxonomyTermTest extends PathTestBase {
    *
    * @var array
    */
-  public static $modules = array('taxonomy');
+  public static $modules = array('taxonomy', 'views');
 
   public static function getInfo() {
     return array(
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php
index 268a247..87469f6 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php
@@ -19,7 +19,7 @@ class TaxonomyAttributesTest extends TaxonomyTestBase {
    *
    * @var array
    */
-  public static $modules = array('rdf');
+  public static $modules = array('rdf', 'views');
 
   public static function getInfo() {
     return array(
diff --git a/core/modules/views/config/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/views.view.taxonomy_term.yml
similarity index 99%
rename from core/modules/views/config/views.view.taxonomy_term.yml
rename to core/modules/taxonomy/config/views.view.taxonomy_term.yml
index ed7c0ba..6f1ec6c 100644
--- a/core/modules/views/config/views.view.taxonomy_term.yml
+++ b/core/modules/taxonomy/config/views.view.taxonomy_term.yml
@@ -2,7 +2,7 @@ base_field: nid
 base_table: node
 core: '8'
 description: 'Content belonging to a certain taxonomy term.'
-status: false
+status: '1'
 display:
   default:
     id: default
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php
index cf49ec6..2b370d9 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php
@@ -19,6 +19,19 @@
 class TaxonomyController extends ControllerBase {
 
   /**
+   * Title callback for term pages.
+   *
+   * @param \Drupal\taxonomy\TermInterface $term
+   *   A taxonomy term entity.
+   *
+   * @return
+   *   The term name to be used as the page title.
+   */
+  public function getTitle(TermInterface $term) {
+    return $term->label();
+  }
+
+  /**
    * Returns a rendered edit form to create a new term associated to the given vocabulary.
    *
    * @param \Drupal\taxonomy\VocabularyInterface $taxonomy_vocabulary
@@ -36,15 +49,6 @@ public function addForm(VocabularyInterface $taxonomy_vocabulary) {
   }
 
   /**
-   * @todo Remove taxonomy_term_page().
-   */
-  public function termPage(TermInterface $taxonomy_term) {
-    module_load_include('pages.inc', 'taxonomy');
-    return taxonomy_term_page($taxonomy_term);
-
-  }
-
-  /**
    * Route title callback.
    *
    * @param \Drupal\taxonomy\VocabularyInterface $taxonomy_vocabulary
@@ -71,11 +75,68 @@ public function termTitle(TermInterface $taxonomy_term) {
   }
 
   /**
-   * @todo Remove taxonomy_term_feed().
+   * Displays all nodes associated with a term.
+   *
+   * @param \Drupal\taxonomy\TermInterface $term
+   *   The taxonomy term entity.
+   *
+   * @return
+   *   A structured array to be rendered by drupal_render().
    */
-  public function termFeed(TermInterface $taxonomy_term) {
-    module_load_include('pages.inc', 'taxonomy');
-    return taxonomy_term_feed($taxonomy_term);
+  public function termPage(TermInterface $term) {
+    // Assign the term name as the page title.
+    drupal_set_title($term->label());
+
+    $build['#attached']['drupal_add_feed'][] = array('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->label());
+
+    foreach ($term->uriRelationships() as $rel) {
+      $uri = $term->uri($rel);
+      // Set the term path as the canonical URL to prevent duplicate content.
+      drupal_add_html_head_link(array('rel' => $rel, 'href' => url($uri['path'], $uri['options'])), TRUE);
+
+      if ($rel == 'canonical') {
+        // Set the non-aliased canonical path as a default shortlink.
+        drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE);
+      }
+    }
+
+    $build['taxonomy_terms'] = taxonomy_term_view_multiple(array($term->id() => $term));
+    if ($nids = taxonomy_select_nodes($term->id(), TRUE, \Drupal::config('node.settings')->get('items_per_page'))) {
+      $nodes = node_load_multiple($nids);
+      $build['nodes'] = node_view_multiple($nodes);
+      $build['pager'] = array(
+        '#theme' => 'pager',
+        '#weight' => 5,
+      );
+    }
+    else {
+      $build['no_content'] = array(
+        '#prefix' => '<p>',
+        '#markup' => t('There is currently no content classified with this term.'),
+        '#suffix' => '</p>',
+      );
+    }
+    return $build;
+  }
+
+  /**
+   * Generate the content feed for a taxonomy term.
+   *
+   * @param \Drupal\taxonomy\TermInterface $term
+   *   The taxonomy term entity.
+   *
+   * @return \Symfony\Component\HttpFoundation\Response
+   *   A response object.
+   */
+  public function termFeed(TermInterface $term) {
+    $channel['link'] = url('taxonomy/term/' . $term->id(), array('absolute' => TRUE));
+    $channel['title'] = \Drupal::config('system.site')->get('name') . ' - ' . $term->label();
+    // Only display the description if we have a single term, to avoid clutter and confusion.
+    // HTML will be removed from feed description.
+    $channel['description'] = check_markup($term->description->value, $term->format->value, '', TRUE);
+    $nids = taxonomy_select_nodes($term->id(), FALSE, \Drupal::config('system.rss')->get('items.limit'));
+
+    return node_feed($nids, $channel);
   }
 
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index c1e9bb2..0ae0f05 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -207,6 +207,7 @@ function testTaxonomyIndex() {
    * Tests that there is a link to the parent term on the child term page.
    */
   function testTaxonomyTermHierarchyBreadcrumbs() {
+    \Drupal::moduleHandler()->install(array('views'));
     // Create two taxonomy terms and set term2 as the parent of term1.
     $term1 = $this->createTerm($this->vocabulary);
     $term2 = $this->createTerm($this->vocabulary);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 83c42c6..35cf63e 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -295,6 +295,7 @@ function testTermAutocompletion() {
    * Save, edit and delete a term using the user interface.
    */
   function testTermInterface() {
+    \Drupal::moduleHandler()->install(array('views'));
     $edit = array(
       'name' => $this->randomName(12),
       'description[value]' => $this->randomName(100),
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php
index 9b4611d..34a805a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php
@@ -52,7 +52,7 @@ function testVocabularyPermissionsTaxonomyTerm() {
     // Edit the term.
     $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
     $this->assertResponse(200);
-    $this->assertText($edit['name'], 'Edit taxonomy term form opened successfully.');
+    $this->assertRaw($edit['name'], 'Edit taxonomy term form opened successfully.');
 
     $edit['name'] = $this->randomName();
     $this->drupalPostForm(NULL, $edit, t('Save'));
@@ -80,7 +80,7 @@ function testVocabularyPermissionsTaxonomyTerm() {
     // Edit the term.
     $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
     $this->assertResponse(200);
-    $this->assertText($term->name->value, 'Edit taxonomy term form opened successfully.');
+    $this->assertRaw($term->name->value, 'Edit taxonomy term form opened successfully.');
 
     $edit['name'] = $this->randomName();
     $this->drupalPostForm(NULL, $edit, t('Save'));
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index bc7b30b..bdbc7c6 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -243,14 +243,10 @@ function taxonomy_menu() {
 
   $items['taxonomy/term/%taxonomy_term'] = array(
     'title' => 'Taxonomy term',
-    'title callback' => 'taxonomy_term_title',
-    'title arguments' => array(2),
     'route_name' => 'taxonomy.term_page',
   );
   $items['taxonomy/term/%taxonomy_term/feed'] = array(
     'title' => 'Taxonomy term',
-    'title callback' => 'taxonomy_term_title',
-    'title arguments' => array(2),
     'route_name' => 'taxonomy.term_feed',
     'type' => MENU_CALLBACK,
   );
@@ -810,19 +806,6 @@ function taxonomy_field_widget_info_alter(&$info) {
 }
 
 /**
- * Title callback for term pages.
- *
- * @param \Drupal\taxonomy\Entity\Term $term
- *   A taxonomy term entity.
- *
- * @return
- *   The term name to be used as the page title.
- */
-function taxonomy_term_title(Term $term) {
-  return $term->label();
-}
-
-/**
  * Form element validate handler for taxonomy term autocomplete element.
  */
 function taxonomy_autocomplete_validate($element, &$form_state) {
diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc
deleted file mode 100644
index d177e1c..0000000
--- a/core/modules/taxonomy/taxonomy.pages.inc
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-/**
- * @file
- * Page callbacks for the taxonomy module.
- */
-
-use Drupal\taxonomy\Entity\Term;
-
-/**
- * Menu callback; displays all nodes associated with a term.
- *
- * @param \Drupal\taxonomy\Entity\Term $term
- *   The taxonomy term entity.
- *
- * @deprecated Use \Drupal\taxonomy\Controller\TaxonomyController::termPage()
- */
-function taxonomy_term_page(Term $term) {
-  $build['#attached']['drupal_add_feed'][] = array('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->label());
-
-  foreach ($term->uriRelationships() as $rel) {
-    // Set the term path as the canonical URL to prevent duplicate content.
-    $build['#attached']['drupal_add_html_head_link'][] = array(
-      array(
-        'rel' => $rel,
-        'href' => $term->url($rel),
-      ),
-      TRUE,
-    );
-
-    if ($rel == 'canonical') {
-      // Set the non-aliased canonical path as a default shortlink.
-      $build['#attached']['drupal_add_html_head_link'][] = array(
-        array(
-          'rel' => 'shortlink',
-          'href' => $term->url($rel, array('alias' => TRUE)),
-        ),
-        TRUE,
-      );
-    }
-  }
-
-  $build['taxonomy_terms'] = taxonomy_term_view_multiple(array($term->id() => $term));
-  if ($nids = taxonomy_select_nodes($term->id(), TRUE, \Drupal::config('node.settings')->get('items_per_page'))) {
-    $nodes = node_load_multiple($nids);
-    $build['nodes'] = node_view_multiple($nodes);
-    $build['pager'] = array(
-      '#theme' => 'pager',
-      '#weight' => 5,
-    );
-  }
-  else {
-    $build['no_content'] = array(
-      '#prefix' => '<p>',
-      '#markup' => t('There is currently no content classified with this term.'),
-      '#suffix' => '</p>',
-    );
-  }
-  return $build;
-}
-
-/**
- * Generate the content feed for a taxonomy term.
- *
- * @param \Drupal\taxonomy\Entity\Term $term
- *   The taxonomy term entity.
- *
- * @deprecated Use \Drupal\taxonomy\Controller\TaxonomyController::termFeed()
- */
-function taxonomy_term_feed(Term $term) {
-  $channel['link'] = url('taxonomy/term/' . $term->id(), array('absolute' => TRUE));
-  $channel['title'] = \Drupal::config('system.site')->get('name') . ' - ' . $term->label();
-  // Only display the description if we have a single term, to avoid clutter and confusion.
-  // HTML will be removed from feed description.
-  $channel['description'] = $term->description->processed;
-  $nids = taxonomy_select_nodes($term->id(), FALSE, \Drupal::config('system.rss')->get('items.limit'));
-
-  return node_feed($nids, $channel);
-}
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
index 7b22ce9..65330e6 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
@@ -256,7 +256,7 @@ public function alterRoutes(RouteCollection $collection) {
         // We assume that the numeric ids of the parameters match the one from
         // the view argument handlers.
         foreach ($parameters as $position => $parameter_name) {
-          $path = str_replace('arg_' . $position, $parameter_name, $path);
+          $path = str_replace('{arg_' . $position . '}', '{' . $parameter_name . '}', $path);
           $argument_map['arg_' . $position] = $parameter_name;
         }
         // Set the corrected path and the mapping to the route object.
diff --git a/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php b/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php
index 96ab152..d60d8d4 100644
--- a/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php
+++ b/core/modules/views/tests/Drupal/views/Tests/Plugin/display/PathPluginBaseTest.php
@@ -252,6 +252,43 @@ public function testAlterRoutesWithParameters() {
   }
 
   /**
+   * Tests alter routes with optional parameter in the overriding route.
+   */
+  public function testAlterRoutesWithOptionalParameters() {
+    $collection = new RouteCollection();
+    $collection->add('test_route', new Route('test_route/{parameter}', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content')));
+
+    list($view) = $this->setupViewExecutableAccessPlugin();
+
+    // Manually setup an argument handler.
+    $argument = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $view->argument['test_id'] = $argument;
+    $view->argument['test_id2'] = $argument;
+
+    $display = array();
+    $display['display_plugin'] = 'page';
+    $display['id'] = 'page_1';
+    $display['display_options'] = array(
+      'path' => 'test_route/%',
+    );
+    $this->pathPlugin->initDisplay($view, $display);
+
+    $view_route_names = $this->pathPlugin->alterRoutes($collection);
+    $this->assertEquals(array('test_id.page_1' => 'test_route'), $view_route_names);
+
+    // Ensure that the test_route is overridden.
+    $route = $collection->get('test_route');
+    $this->assertInstanceOf('\Symfony\Component\Routing\Route', $route);
+    $this->assertEquals('test_id', $route->getDefault('view_id'));
+    $this->assertEquals('page_1', $route->getDefault('display_id'));
+    // Ensure that the path did not changed and placeholders are respected.
+    $this->assertEquals('/test_route/{parameter}/{arg_test_id2}', $route->getPath());
+    $this->assertEquals(array('arg_test_id' => 'parameter'), $route->getDefault('_view_argument_map'));
+  }
+
+  /**
    * Returns some mocked view entity, view executable, and access plugin.
    */
   protected function setupViewExecutableAccessPlugin() {
