diff --git includes/menu.inc includes/menu.inc index bae3750..11ff197 100644 --- includes/menu.inc +++ includes/menu.inc @@ -1057,7 +1057,19 @@ function menu_tree_page_data($menu_name, $max_depth = NULL) { $tree = &drupal_static(__FUNCTION__, array()); // Load the menu item corresponding to the current page. - if ($item = menu_get_item()) { + $active_trail = menu_get_active_trail(); + // Find the deepest item in the active trail that is in the menu system. + do { + $item = array_pop($active_trail); + } while (isset($item) && $item['type'] == 0); + if (!empty($item['href'])) { + $item = menu_get_item($item['href']); + } + // If we didn't find a menu item, load the menu item corresponding to the current page. + if (!$item) { + $item = menu_get_item(); + } + if ($item) { if (isset($max_depth)) { $max_depth = min($max_depth, MENU_MAX_DEPTH); } @@ -1271,6 +1283,8 @@ function _menu_build_tree($menu_name, array $parameters = array()) { } $active_link = (isset($parameters['active_trail']) ? $parameters['active_trail'] : array()); $data['tree'] = menu_tree_data($links, $active_link, $min_depth); + // Allow the tree to be altered before any access checks. + drupal_alter('menu_tree', $data['tree'], $parameters); $data['node_links'] = array(); menu_tree_collect_node_links($data['tree'], $data['node_links']); @@ -2105,6 +2119,11 @@ function menu_set_active_item($path) { /** * Sets or gets the active trail (path to root menu root) of the current page. * + * If a trail is set, it must exist in the menu system since this trail is used + * by menu_tree_page_data() and menu_get_active_breadcrumb() when determining + * the menu's active trail. In order to set a trail that does not exist in the + * menu system, use drupal_set_breadcrumb() instead. + * * @param $new_trail * Menu trail to set, or NULL to use previously-set or calculated trail. If * supplying a trail, use the same format as the return value (see below). @@ -2193,9 +2212,9 @@ function menu_set_active_trail($new_trail = NULL) { } } // Make sure the current page is in the trail (needed for the page title), - // but exclude tabs and the front page. + // but exclude default tabs and the front page. $last = count($trail) - 1; - if ($trail[$last]['href'] != $item['href'] && !(bool) ($item['type'] & MENU_IS_LOCAL_TASK) && !drupal_is_front_page()) { + if ($trail[$last]['href'] != $item['href'] && !(bool) ($item['type'] & MENU_LINKS_TO_PARENT) && !drupal_is_front_page()) { $trail[] = $item; } } @@ -2222,20 +2241,18 @@ function menu_get_active_breadcrumb() { return $breadcrumb; } - $item = menu_get_item(); - if ($item && $item['access']) { - $active_trail = menu_get_active_trail(); + $active_trail = menu_get_active_trail(); - foreach ($active_trail as $parent) { - $breadcrumb[] = l($parent['title'], $parent['href'], $parent['localized_options']); - } - $end = end($active_trail); + foreach ($active_trail as $parent) { + $breadcrumb[] = l($parent['title'], $parent['href'], $parent['localized_options']); + } + $end = end($active_trail); - // Don't show a link to the current page in the breadcrumb trail. - if ($item['href'] == $end['href'] || (($item['type'] & MENU_LINKS_TO_PARENT) == MENU_LINKS_TO_PARENT && $end['href'] != '')) { - array_pop($breadcrumb); - } + // Don't show a link to the current page in the breadcrumb trail. + if ($end['href'] != '') { + array_pop($breadcrumb); } + return $breadcrumb; } diff --git modules/system/system.api.php modules/system/system.api.php index d8450db..57b1f75 100644 --- modules/system/system.api.php +++ modules/system/system.api.php @@ -1244,6 +1244,27 @@ function hook_menu_contextual_links_alter(&$links, $router_item, $root_path) { } /** + * Alter menu trees before they are rendered. + * + * This hook is invoked by menu_build_tree(). The tree is passed through + * menu_tree_check_access() after this hook is called, so implementations will + * not need to worry about node access for any altered items. + * + * @param $tree + * The menu tree to be altered. + * @param $parameters + * An associative array of build parameters passed to menu_build_tree(). + */ +function hook_menu_tree_alter(&$tree, $parameters = array()) { + // Add a "primary" class to each of the first-level links. + foreach ($data['tree'] as $mlid => &$item) { + $options = unserialize($item['link']['options']); + $options['attributes']['class'][] = 'primary'; + $item['link']['options'] = serialize($options); + } +} + +/** * Perform alterations before a page is rendered. * * Use this hook when you want to remove or alter elements at the page