Issue #2011006 by tim.plunkett: Fixed Default local tasks provided by Views are broken.
parent
56f4362ad4
commit
edb0095ee2
|
@ -2723,25 +2723,6 @@ function menu_router_build($save = FALSE) {
|
||||||
$router_items = call_user_func($module . '_menu');
|
$router_items = call_user_func($module . '_menu');
|
||||||
if (isset($router_items) && is_array($router_items)) {
|
if (isset($router_items) && is_array($router_items)) {
|
||||||
foreach (array_keys($router_items) as $path) {
|
foreach (array_keys($router_items) as $path) {
|
||||||
// If the menu item is a default local task and incorrectly references a
|
|
||||||
// route, remove it.
|
|
||||||
// @todo This may be removed later depending on the outcome of
|
|
||||||
// http://drupal.org/node/1889790
|
|
||||||
if (isset($router_items[$path]['type']) && $router_items[$path]['type'] == MENU_DEFAULT_LOCAL_TASK) {
|
|
||||||
unset($router_items[$path]['route_name']);
|
|
||||||
}
|
|
||||||
// If the menu item references a route, normalize the route information
|
|
||||||
// into the old structure. Note that routes are keyed by name, not path,
|
|
||||||
// so the path of the route takes precedence.
|
|
||||||
if (isset($router_items[$path]['route_name'])) {
|
|
||||||
$router_item = $router_items[$path];
|
|
||||||
$router_item['page callback'] = 'USES_ROUTE';
|
|
||||||
$router_item['access callback'] = TRUE;
|
|
||||||
$new_path = _menu_router_translate_route($router_item['route_name']);
|
|
||||||
unset($router_items[$path]);
|
|
||||||
$router_items[$new_path] = $router_item;
|
|
||||||
$path = $new_path;
|
|
||||||
}
|
|
||||||
$router_items[$path]['module'] = $module;
|
$router_items[$path]['module'] = $module;
|
||||||
}
|
}
|
||||||
$callbacks = array_merge($callbacks, $router_items);
|
$callbacks = array_merge($callbacks, $router_items);
|
||||||
|
@ -2749,6 +2730,26 @@ function menu_router_build($save = FALSE) {
|
||||||
}
|
}
|
||||||
// Alter the menu as defined in modules, keys are like user/%user.
|
// Alter the menu as defined in modules, keys are like user/%user.
|
||||||
drupal_alter('menu', $callbacks);
|
drupal_alter('menu', $callbacks);
|
||||||
|
foreach ($callbacks as $path => $router_item) {
|
||||||
|
// If the menu item is a default local task and incorrectly references a
|
||||||
|
// route, remove it.
|
||||||
|
// @todo This may be removed later depending on the outcome of
|
||||||
|
// http://drupal.org/node/1889790
|
||||||
|
if (isset($router_item['type']) && $router_item['type'] == MENU_DEFAULT_LOCAL_TASK) {
|
||||||
|
unset($callbacks[$path]['route_name']);
|
||||||
|
}
|
||||||
|
// If the menu item references a route, normalize the route information
|
||||||
|
// into the old structure. Note that routes are keyed by name, not path,
|
||||||
|
// so the path of the route takes precedence.
|
||||||
|
if (isset($router_item['route_name'])) {
|
||||||
|
$router_item['page callback'] = 'USES_ROUTE';
|
||||||
|
$router_item['access callback'] = TRUE;
|
||||||
|
$new_path = _menu_router_translate_route($router_item['route_name']);
|
||||||
|
|
||||||
|
unset($callbacks[$path]);
|
||||||
|
$callbacks[$new_path] = $router_item;
|
||||||
|
}
|
||||||
|
}
|
||||||
list($menu, $masks) = _menu_router_build($callbacks, $save);
|
list($menu, $masks) = _menu_router_build($callbacks, $save);
|
||||||
_menu_router_cache($menu);
|
_menu_router_cache($menu);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,29 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getPath() {
|
||||||
|
$bits = explode('/', $this->getOption('path'));
|
||||||
|
if ($this->isDefaultTabPath()) {
|
||||||
|
array_pop($bits);
|
||||||
|
}
|
||||||
|
return implode('/', $bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this display's path is a default tab.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE if the display path is for a default tab, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
protected function isDefaultTabPath() {
|
||||||
|
$menu = $this->getOption('menu');
|
||||||
|
$tab_options = $this->getOption('tab_options');
|
||||||
|
return $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase:defineOptions().
|
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase:defineOptions().
|
||||||
*/
|
*/
|
||||||
|
@ -84,6 +107,14 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
|
||||||
$bits[] = $bit;
|
$bits[] = $bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is to be a default tab, create the route for the parent path.
|
||||||
|
if ($this->isDefaultTabPath()) {
|
||||||
|
$bit = array_pop($bits);
|
||||||
|
if ($bit == '%views_arg' || empty($bits)) {
|
||||||
|
$bits[] = $bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$route_path = '/' . implode('/', $bits);
|
$route_path = '/' . implode('/', $bits);
|
||||||
|
|
||||||
$route = new Route($route_path, $defaults);
|
$route = new Route($route_path, $defaults);
|
||||||
|
@ -172,38 +203,42 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
|
||||||
|
|
||||||
// If this is a 'default' tab, check to see if we have to create the
|
// If this is a 'default' tab, check to see if we have to create the
|
||||||
// parent menu item.
|
// parent menu item.
|
||||||
if ($menu['type'] == 'default tab') {
|
if ($this->isDefaultTabPath()) {
|
||||||
$tab_options = $this->getOption('tab_options');
|
$tab_options = $this->getOption('tab_options');
|
||||||
if (!empty($tab_options['type']) && $tab_options['type'] != 'none') {
|
|
||||||
$bits = explode('/', $path);
|
|
||||||
// Remove the last piece.
|
|
||||||
$bit = array_pop($bits);
|
|
||||||
|
|
||||||
// we can't do this if they tried to make the last path bit variable.
|
$bits = explode('/', $path);
|
||||||
// @todo: We can validate this.
|
// Remove the last piece.
|
||||||
if ($bit != '%views_arg' && !empty($bits)) {
|
$bit = array_pop($bits);
|
||||||
$default_path = implode('/', $bits);
|
|
||||||
$items[$default_path] = array(
|
// we can't do this if they tried to make the last path bit variable.
|
||||||
// Default views page entry.
|
// @todo: We can validate this.
|
||||||
// Identify URL embedded arguments and correlate them to a
|
if ($bit != '%views_arg' && !empty($bits)) {
|
||||||
// handler.
|
// Assign the route name to the parent route, not the default tab.
|
||||||
'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'),
|
$default_route_name = $items[$path]['route_name'];
|
||||||
'title' => $tab_options['title'],
|
unset($items[$path]['route_name']);
|
||||||
'description' => $tab_options['description'],
|
|
||||||
'menu_name' => $tab_options['name'],
|
$default_path = implode('/', $bits);
|
||||||
);
|
$items[$default_path] = array(
|
||||||
switch ($tab_options['type']) {
|
// Default views page entry.
|
||||||
default:
|
// Identify URL embedded arguments and correlate them to a
|
||||||
case 'normal':
|
// handler.
|
||||||
$items[$default_path]['type'] = MENU_NORMAL_ITEM;
|
'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'),
|
||||||
break;
|
'title' => $tab_options['title'],
|
||||||
case 'tab':
|
'description' => $tab_options['description'],
|
||||||
$items[$default_path]['type'] = MENU_LOCAL_TASK;
|
'menu_name' => $tab_options['name'],
|
||||||
break;
|
'route_name' => $default_route_name,
|
||||||
}
|
);
|
||||||
if (isset($tab_options['weight'])) {
|
switch ($tab_options['type']) {
|
||||||
$items[$default_path]['weight'] = intval($tab_options['weight']);
|
default:
|
||||||
}
|
case 'normal':
|
||||||
|
$items[$default_path]['type'] = MENU_NORMAL_ITEM;
|
||||||
|
break;
|
||||||
|
case 'tab':
|
||||||
|
$items[$default_path]['type'] = MENU_LOCAL_TASK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isset($tab_options['weight'])) {
|
||||||
|
$items[$default_path]['weight'] = intval($tab_options['weight']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ class DisplayPageWebTest extends PluginTestBase {
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $testViews = array('test_page_display_arguments');
|
public static $testViews = array('test_page_display_arguments', 'test_page_display_menu');
|
||||||
|
|
||||||
public static function getInfo() {
|
public static function getInfo() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -69,4 +69,30 @@ class DisplayPageWebTest extends PluginTestBase {
|
||||||
$this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
|
$this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests menu settings of page displays.
|
||||||
|
*/
|
||||||
|
public function testPageDisplayMenu() {
|
||||||
|
$this->drupalGet('test_page_display_menu');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', array(
|
||||||
|
':ul_class' => 'tabs primary',
|
||||||
|
':a_class' => 'active',
|
||||||
|
));
|
||||||
|
$this->assertEqual((string) $element[0], t('Test default tab'));
|
||||||
|
$this->assertTitle(t('Test default page | Drupal'));
|
||||||
|
|
||||||
|
$this->drupalGet('test_page_display_menu/default');
|
||||||
|
$this->assertResponse(404);
|
||||||
|
|
||||||
|
$this->drupalGet('test_page_display_menu/local');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', array(
|
||||||
|
':ul_class' => 'tabs primary',
|
||||||
|
':a_class' => 'active',
|
||||||
|
));
|
||||||
|
$this->assertEqual((string) $element[0], t('Test local tab'));
|
||||||
|
$this->assertTitle(t('Test local page | Drupal'));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
base_table: views_test_data
|
||||||
|
base_field: id
|
||||||
|
core: '8'
|
||||||
|
description: ''
|
||||||
|
status: '1'
|
||||||
|
display:
|
||||||
|
default:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
fields: '0'
|
||||||
|
pager: '0'
|
||||||
|
pager_options: '0'
|
||||||
|
sorts: '0'
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
id: id
|
||||||
|
table: views_test_data
|
||||||
|
field: id
|
||||||
|
plugin_id: numeric
|
||||||
|
display_plugin: default
|
||||||
|
display_title: Master
|
||||||
|
id: default
|
||||||
|
position: '0'
|
||||||
|
page_1:
|
||||||
|
display_options:
|
||||||
|
path: test_page_display_menu/default
|
||||||
|
title: 'Test default page'
|
||||||
|
menu:
|
||||||
|
type: 'default tab'
|
||||||
|
title: 'Test default tab'
|
||||||
|
description: ''
|
||||||
|
name: tools
|
||||||
|
weight: '-10'
|
||||||
|
context: '0'
|
||||||
|
tab_options:
|
||||||
|
type: normal
|
||||||
|
title: 'Test parent path'
|
||||||
|
description: ''
|
||||||
|
name: tools
|
||||||
|
weight: '0'
|
||||||
|
defaults:
|
||||||
|
title: '0'
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_1
|
||||||
|
position: '0'
|
||||||
|
page_2:
|
||||||
|
display_options:
|
||||||
|
path: test_page_display_menu/local
|
||||||
|
title: 'Test local page'
|
||||||
|
menu:
|
||||||
|
type: tab
|
||||||
|
title: 'Test local tab'
|
||||||
|
description: ''
|
||||||
|
name: tools
|
||||||
|
weight: '0'
|
||||||
|
context: '0'
|
||||||
|
defaults:
|
||||||
|
title: '0'
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_2
|
||||||
|
position: '0'
|
||||||
|
label: 'Test page menu'
|
||||||
|
id: test_page_display_menu
|
||||||
|
tag: ''
|
Loading…
Reference in New Issue