1. drupal
    1. 8
    2. 7
7 – 8 menu_link_get_preferred($path = NULL)

Lookup the preferred menu link for a given system path.


$path The path, for example 'node/5'. The function will find the corresponding menu link ('node/5' if it exists, or fallback to 'node/%').

Return value

A fully translated menu link, or NULL if no matching menu link was found. The most specific menu link ('node/5' preferred over 'node/%') in the most preferred menu (as defined by menu_get_active_menu_names()) is returned.

Related topics

▾ 2 functions call menu_link_get_preferred()

menu_set_active_trail in includes/
Sets the active trail (path to menu tree root) of the current page.
menu_tree_page_data in includes/
Get the data structure representing a named menu tree, based on the current page.


includes/, line 2384

function menu_link_get_preferred($path = NULL) {
  $preferred_links = &drupal_static(__FUNCTION__);

  if (!isset($path)) {
    $path = $_GET['q'];

  if (!isset($preferred_links[$path])) {
    $preferred_links[$path] = FALSE;

    // Look for the correct menu link by building a list of candidate paths,
    // which are ordered by priority (translated hrefs are preferred over
    // untranslated paths). Afterwards, the most relevant path is picked from
    // the menus, ordered by menu preference.
    $item = menu_get_item($path);
    $path_candidates = array();
    // 1. The current item href.
    $path_candidates[$item['href']] = $item['href'];
    // 2. The tab root href of the current item (if any).
    if ($item['tab_parent'] && ($tab_root = menu_get_item($item['tab_root_href']))) {
      $path_candidates[$tab_root['href']] = $tab_root['href'];
    // 3. The current item path (with wildcards).
    $path_candidates[$item['path']] = $item['path'];
    // 4. The tab root path of the current item (if any).
    if (!empty($tab_root)) {
      $path_candidates[$tab_root['path']] = $tab_root['path'];

    // Retrieve a list of menu names, ordered by preference.
    $menu_names = menu_get_active_menu_names();

    $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
    $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
    // Weight must be taken from {menu_links}, not {menu_router}.
    $query->addField('ml', 'weight', 'link_weight');
    $query->condition('ml.menu_name', $menu_names, 'IN');
    $query->condition('ml.link_path', $path_candidates, 'IN');

    // Sort candidates by link path and menu name.
    $candidates = array();
    foreach ($query->execute() as $candidate) {
      $candidate['weight'] = $candidate['link_weight'];
      $candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;

    // Pick the most specific link, in the most preferred menu.
    foreach ($path_candidates as $link_path) {
      if (!isset($candidates[$link_path])) {
      foreach ($menu_names as $menu_name) {
        if (!isset($candidates[$link_path][$menu_name])) {
        $candidate_item = $candidates[$link_path][$menu_name];
        $map = explode('/', $path);
        _menu_translate($candidate_item, $map);
        if ($candidate_item['access']) {
          $preferred_links[$path] = $candidate_item;
        break 2;

  return $preferred_links[$path];