diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index fdcabf3..4e5c4b7 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -742,10 +742,13 @@ public function getPath() { * {@inheritdoc} */ public function getRoutedDisplay() { + // If this display has a route, return this display. if ($this instanceof DisplayRouterInterface) { return $this; } + // If the display does not have a route (e.g. a block display), get the + // route for the linked display. $display_id = $this->getLinkDisplay(); if ($display_id && $this->view->displayHandlers->has($display_id) && is_object($this->view->displayHandlers->get($display_id))) { return $this->view->displayHandlers->get($display_id)->getRoutedDisplay(); @@ -2033,15 +2036,20 @@ public function renderPager() { */ public function renderMoreLink() { if ($this->isMoreEnabled() && ($this->useMoreAlways() || (!empty($this->view->pager) && $this->view->pager->hasMoreRecords()))) { + // If the user has supplied a custom "More" link path, replace any + // argument tokens and use that for the URL. if ($this->getOption('link_display') == 'custom_url' && $override_path = $this->getOption('link_url')) { $tokens = $this->getArgumentsTokens(); $path = $this->viewsTokenReplace($override_path, $tokens); $url = Url::fromUri('user-path:' . $path); } + // Otherwise, use the URL for the display. else { $url = $this->view->getUrl(NULL, $this->display['id']); } + // If a URL is available (either from the display or a custom path), + // render the "More" link. if ($url) { $url_options = array(); if (!empty($this->view->exposed_raw_input)) { diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php index 6facee1..c91416e 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php @@ -216,15 +216,17 @@ public function getPath(); /** * Points to the display which can be linked by this display. * - * If $this display has route information it returns itself, otherwise it is - * the configured linked display. + * If the display has route information, the display itself is returned. + * Otherwise, the configured linked display is returned. For example, if a + * block display links to a page display, the page display will be returned + * in both cases. * * @return static|null */ public function getRoutedDisplay(); /** - * Returns a URL to $this display or its configured linked display + * Returns a URL to $this display or its configured linked display. * * @return \Drupal\Core\Url|null */ diff --git a/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php b/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php index e0bc92f..80d86d5 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php +++ b/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php @@ -49,9 +49,26 @@ public function getUrlInfo(); /** * Returns the route name for the display. * + * The default route name for a display is views.view_id.display_id. Some + * displays may override existing routes; in these cases, the route that is + * overridden is returned instead. + * * @return string * The name of the route + * + * @see \Drupal\views\Plugin\views\display\DisplayRouterInterface::alterRoutes() + * @see \Drupal\views\Plugin\views\display\DisplayRouterInterface::getAlteredRouteNames() */ public function getRouteName(); + /** + * Returns the list of routes overridden by Views. + * + * @return string[] + * An array of overridden route names. The keys are in the form + * view_id.display_id and the values are the route names. + * + * @see \Drupal\views\Plugin\views\display\DisplayRouterInterface::alterRoutes() + */ + public function getAlteredRouteNames(); } diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php index 9f82edd..1998040 100644 --- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php @@ -294,8 +294,6 @@ public function getMenuLinks() { } } - $view_route_names = $this->state->get('views.view_route_names') ?: array(); - $path = implode('/', $bits); $view_id = $this->view->storage->id(); $display_id = $this->display['id']; @@ -309,7 +307,7 @@ public function getMenuLinks() { // Some views might override existing paths, so we have to set the route // name based upon the altering. $links[$menu_link_id] = array( - 'route_name' => isset($view_route_names[$view_id_display]) ? $view_route_names[$view_id_display] : "view.$view_id_display", + 'route_name' => $this->getRouteName(); // Identify URL embedded arguments and correlate them to a handler. 'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'), 'id' => $menu_link_id, @@ -502,8 +500,16 @@ public function getRouteName() { $view_route_key = "$view_id.$display_id"; // Check for overridden route names. - $view_route_names = $this->state->get('views.view_route_names') ?: array(); + $view_route_names = $this->getAlteredRouteNames(); return (isset($view_route_names[$view_route_key]) ? $view_route_names[$view_route_key] : "views.$view_route_key"); } + + /** + * {@inheritdoc + */ + public function getAlteredRouteNames() { + return $this->state->get('views.view_route_names') ?: array(); + } + } diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php index 532fe84..db01ad8 100644 --- a/core/modules/views/src/ViewExecutable.php +++ b/core/modules/views/src/ViewExecutable.php @@ -1705,12 +1705,15 @@ public function buildTitle() { } /** - * Determines whether you can link to the View. + * Determines whether you can link to the view or a particular display. + * + * Some displays (e.g. block displays) do not have their own route, but may + * optionally provide a link to another display that does have a route. * * @param array $args * (optional) The arguments. * @param string $display_id - * (optional) The display ID. + * (optional) The display ID. The current display will be used by default. * * @return bool */ @@ -1719,6 +1722,8 @@ public function hasUrl($args = NULL, $display_id = NULL) { return TRUE; } + // If the display has a valid route available (either its own or for a + // linked display), then we can provide a URL for it. $display_handler = $this->displayHandlers->get($display_id ?: $this->current_display)->getRoutedDisplay(); if (!$display_handler instanceof DisplayRouterInterface) { return FALSE;