diff --git includes/menu.inc includes/menu.inc index ecfeebf..2a57666 100644 --- includes/menu.inc +++ includes/menu.inc @@ -2347,6 +2347,8 @@ function menu_get_active_trail() { /** * Get the breadcrumb for the current page, as determined by the active trail. + * + * @see menu_set_active_trail() */ function menu_get_active_breadcrumb() { $breadcrumb = array(); @@ -2360,6 +2362,10 @@ function menu_get_active_breadcrumb() { if (!empty($item['access'])) { $active_trail = menu_get_active_trail(); + // Allow modules to alter the breadcrumb, if possible, as that is much + // faster than rebuilding an entirely new active trail. + drupal_alter('menu_breadcrumb', $active_trail, $item); + // Don't show a link to the current page in the breadcrumb trail. $end = end($active_trail); if ($item['href'] == $end['href']) { diff --git modules/system/system.api.php modules/system/system.api.php index d8450db..7dbbe30 100644 --- modules/system/system.api.php +++ modules/system/system.api.php @@ -1200,6 +1200,53 @@ function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) { } /** + * Alter links in the active trail (breadcrumb) before it is rendered. + * + * This hook is invoked by menu_get_active_breadcrumb() and allows to alter + * the breadcrumb links for the current page, which may be preferred instead + * of setting a custom breadcrumb via drupal_set_breadcrumb(). + * + * Implementations should take into account that menu_get_active_breadcrumb() + * subsequently performs the following adjustments to the active trail *after* + * this hook has been invoked: + * - The last link in $active_trail is removed, if its 'href' is identical to + * the 'href' of $item. This happens, because the breadcrumb normally does + * not contain a link to the current page. + * - The (second to) last link in $active_trail is removed, if the current $item + * is a MENU_DEFAULT_LOCAL_TASK. This happens in order to do not show a link + * to the current page, when being on the path for the default local task; + * e.g. when being on the path node/%/view, the breadcrumb should not contain + * a link to node/%. + * + * Each link in the active trail must contain: + * - title: The localized title of the link. + * - href: The system path to link to. + * - localized_options: An array of options to pass to url(). + * + * @param $active_trail + * An array containing breadcrumb links for the current page. + * @param $item + * The menu router item of the current page. + * + * @see drupal_set_breadcrumb() + * @see menu_get_active_breadcrumb() + * @see menu_get_active_trail() + * @see menu_set_active_trail() + */ +function hook_menu_breadcrumb_alter(&$active_trail, $item) { + // Always display a link to the current page by duplicating the last link in + // the active trail. This means that menu_get_active_breadcrumb() will remove + // the last link (for the current page), but since it is added once more here, + // it will appear. + if (!drupal_is_front_page()) { + $end = end($active_trail); + if ($item['href'] == $end['href']) { + $active_trail[] = $end; + } + } +} + +/** * Alter contextual links before they are rendered. * * This hook is invoked by menu_contextual_links(). The system-determined