diff --git includes/menu.inc includes/menu.inc index 1daee3c..2ee77b9 100644 --- includes/menu.inc +++ includes/menu.inc @@ -113,6 +113,11 @@ define('MENU_CREATED_BY_ADMIN', 0x0040); define('MENU_IS_LOCAL_TASK', 0x0080); /** + * Internal menu flag -- menu item is a local action. + */ +define('MENU_IS_LOCAL_ACTION', 0x0100); + +/** * @} End of "Menu flags". */ @@ -168,6 +173,14 @@ define('MENU_LOCAL_TASK', MENU_IS_LOCAL_TASK); define('MENU_DEFAULT_LOCAL_TASK', MENU_IS_LOCAL_TASK | MENU_LINKS_TO_PARENT); /** + * Menu type -- An action specific to the parent, usually rendered as a link. + * + * Local actions are menu items that describe actions on the parent item such + * as adding a new user, taxonomy term, etc. + */ +define('MENU_LOCAL_ACTION', MENU_IS_LOCAL_TASK | MENU_IS_LOCAL_ACTION); + +/** * @} End of "Menu item types". */ @@ -1437,27 +1450,36 @@ function menu_navigation_links($menu_name, $level = 0) { } /** - * Collects the local tasks (tabs) for a given level. + * Collects the local tasks (tabs), actions (links) and the root path. * * @param $level * The level of tasks you ask for. Primary tasks are 0, secondary are 1. * @param $return_root * Whether to return the root path for the current page. * @return - * Themed output corresponding to the tabs of the requested level, or - * router path if $return_root == TRUE. This router path corresponds to + * Array containing themed output corresponding to the tabs of the requested + * level and the actions for the current page, and a + * router path. This router path corresponds to * a parent tab, if the current page is a default local task. */ -function menu_local_tasks($level = 0, $return_root = FALSE) { - $tabs = &drupal_static(__FUNCTION__); - $root_path = &drupal_static(__FUNCTION__ . ':root_path'); +function menu_local_tasks($level = 0) { + $data = &drupal_static(__FUNCTION__); + $root_path = &drupal_static(__FUNCTION__ . ':root_path', ''); + $empty = array( + 'tabs' => array('count' => 0, 'output' => ''), + 'actions' => array('count' => 0, 'output' => ''), + 'root_path' => $root_path, + ); - if (!isset($tabs)) { + if (!isset($data)) { + $data = array(); + // Set defaults in case there are no actions or tabs. + $actions = $empty['actions']; $tabs = array(); $router_item = menu_get_item(); if (!$router_item || !$router_item['access']) { - return ''; + return $empty; } // Get all tabs and the root page. $result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC)) @@ -1480,7 +1502,6 @@ function menu_local_tasks($level = 0, $return_root = FALSE) { // Store the translated item for later use. $tasks[$item['path']] = $item; } - // Find all tabs below the current path. $path = $router_item['path']; // Tab parenting may skip levels, so the number of parts in the path may not @@ -1488,31 +1509,43 @@ function menu_local_tasks($level = 0, $return_root = FALSE) { $depth = 1001; while (isset($children[$path])) { $tabs_current = ''; + $actions_current = ''; $next_path = ''; - $count = 0; + $tab_count = 0; + $action_count = 0; foreach ($children[$path] as $item) { if ($item['access']) { - $count++; // The default task is always active. if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) { - // Find the first parent which is not a default local task. + // Find the first parent which is not a default local task or action. for ($p = $item['tab_parent']; $tasks[$p]['type'] == MENU_DEFAULT_LOCAL_TASK; $p = $tasks[$p]['tab_parent']); $link = theme('menu_item_link', array('href' => $tasks[$p]['href']) + $item); $tabs_current .= theme('menu_local_task', $link, TRUE); $next_path = $item['path']; + $tab_count++; } else { $link = theme('menu_item_link', $item); - $tabs_current .= theme('menu_local_task', $link); + if ($item['type'] == MENU_LOCAL_TASK) { + $tabs_current .= theme('menu_local_task', $link); + $tab_count++; + } + else { + // @todo: add a different theme function. + $actions_current .= theme('menu_local_task', $link); + $action_count++; + } } } } $path = $next_path; - $tabs[$depth]['count'] = $count; + $tabs[$depth]['count'] = $tab_count; $tabs[$depth]['output'] = $tabs_current; + $actions['count'] = $action_count; + $actions['output'] = $actions_current; $depth++; } - + $data['actions'] = $actions; // Find all tabs at the same level or above the current one. $parent = $router_item['tab_parent']; $path = $router_item['path']; @@ -1524,6 +1557,9 @@ function menu_local_tasks($level = 0, $return_root = FALSE) { $next_parent = ''; $count = 0; foreach ($children[$parent] as $item) { + if ($item['type'] == MENU_LOCAL_ACTION) { + continue; + } if ($item['access']) { $count++; if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) { @@ -1560,36 +1596,44 @@ function menu_local_tasks($level = 0, $return_root = FALSE) { ksort($tabs); // Remove the depth, we are interested only in their relative placement. $tabs = array_values($tabs); + $data['tabs'] = $tabs; } - if ($return_root) { - return $root_path; - } - else { - // We do not display single tabs. - return (isset($tabs[$level]) && $tabs[$level]['count'] > 1) ? $tabs[$level]['output'] : ''; - } + return (isset($data['tabs'][$level])) ? array('tabs' => $data['tabs'][$level], 'actions' => $data['actions'], 'root_path' => $root_path) : $empty; } /** * Returns the rendered local tasks at the top level. */ function menu_primary_local_tasks() { - return menu_local_tasks(0); + $links = menu_local_tasks(0); + // We do not display single tabs. + return ($links['tabs']['count'] > 1) ? $links['tabs']['output'] : ''; } /** * Returns the rendered local tasks at the second level. */ function menu_secondary_local_tasks() { - return menu_local_tasks(1); + $links = menu_local_tasks(1); + // We do not display single tabs. + return ($links['tabs']['count'] > 1) ? $links['tabs']['output'] : ''; +} + +/** + * Returns the rendered local actions at the current level. + */ +function menu_local_actions() { + $links = menu_local_tasks(); + return $links['actions']['output']; } /** * Returns the router path, or the path of the parent tab of a default local task. */ function menu_tab_root_path() { - return menu_local_tasks(0, TRUE); + $links = menu_local_tasks(); + return $links['root_path']; } /** @@ -2586,7 +2630,7 @@ function _menu_router_build($callbacks) { ); $item += array( '_visible' => (bool)($item['type'] & MENU_VISIBLE_IN_BREADCRUMB), - '_tab' => (bool)($item['type'] & MENU_IS_LOCAL_TASK), + '_is_task' => (bool)($item['type'] & MENU_IS_LOCAL_TASK), ); if ($move) { $new_path = implode('/', $item['_parts']); @@ -2602,7 +2646,7 @@ function _menu_router_build($callbacks) { // Apply inheritance rules. foreach ($menu as $path => $v) { $item = &$menu[$path]; - if (!$item['_tab']) { + if (!$item['_is_task']) { // Non-tab items. $item['tab_parent'] = ''; $item['tab_root'] = $path; @@ -2617,7 +2661,7 @@ function _menu_router_build($callbacks) { // Parent stores the parent of the path. $item['tab_parent'] = $parent_path; } - if (!isset($item['tab_root']) && !$parent['_tab']) { + if (!isset($item['tab_root']) && !$parent['_is_task']) { $item['tab_root'] = $parent_path; } // If an access callback is not found for a default local task we use diff --git modules/menu/menu.module modules/menu/menu.module index f6daaac..bed0337 100644 --- modules/menu/menu.module +++ modules/menu/menu.module @@ -65,7 +65,7 @@ function menu_menu() { 'page callback' => 'drupal_get_form', 'page arguments' => array('menu_edit_menu', 'add'), 'access arguments' => array('administer menu'), - 'type' => MENU_LOCAL_TASK, + 'type' => MENU_LOCAL_ACTION, ); $items['admin/structure/menu/settings'] = array( 'title' => 'Settings', @@ -94,7 +94,7 @@ function menu_menu() { 'page callback' => 'drupal_get_form', 'page arguments' => array('menu_edit_item', 'add', NULL, 3), 'access arguments' => array('administer menu'), - 'type' => MENU_LOCAL_TASK, + 'type' => MENU_LOCAL_ACTION, ); $items['admin/structure/menu-customize/%menu/edit'] = array( 'title' => 'Edit menu', diff --git themes/seven/page.tpl.php themes/seven/page.tpl.php index 68b73c6..b85e928 100644 --- themes/seven/page.tpl.php +++ themes/seven/page.tpl.php @@ -33,6 +33,7 @@ + diff --git themes/seven/style.css themes/seven/style.css index ff02a11..daf035c 100644 --- themes/seven/style.css +++ themes/seven/style.css @@ -697,7 +697,8 @@ div.admin-options div.form-item { border: 0; } -a.node-admin-add-content { +a.node-admin-add-content, +ul.local-actions li a { padding-left: 15px; background: url(images/add.png) no-repeat 0 center; line-height: 30px; diff --git themes/seven/template.php themes/seven/template.php index fec6302..2194424 100644 --- themes/seven/template.php +++ themes/seven/template.php @@ -7,6 +7,7 @@ function seven_preprocess_page(&$vars) { $vars['primary_local_tasks'] = menu_primary_local_tasks(); $vars['secondary_local_tasks'] = menu_secondary_local_tasks(); + $vars['local_actions'] = menu_local_actions(); $vars['ie_styles'] = ''; $vars['back_to_site'] = l(t('Back to the front page'), ''); }