Restrict menu tree to first level

2019-07-23 06:27发布

问题:

I've been struggling a while in order to get my primary links to display only the first level entries (roots). I have the following code in my template.php :

I've tried changing the $level variable to 0 but no effect. I don't know where (the hell) to stop the recursion.

function supertheme_navigation_links($menu_name, $level = 2) {
  // Don't even bother querying the menu table if no menu is specified.
  if (empty($menu_name)) {
    return array();
  }
  // Get the menu hierarchy for the current page.
  $tree_page = menu_tree_page_data($menu_name);
  // Also get the full menu hierarchy.
  $tree_all = menu_tree_all_data($menu_name);
  // Go down the active trail until the right level is reached.
  while ($level-- > 0 && $tree_page) {
    // Loop through the current level's items until we find one that is in trail.
    while ($item = array_shift($tree_page)) {
      if ($item['link']['in_active_trail']) {
        // If the item is in the active trail, we continue in the subtree.
        $tree_page = empty($item['below']) ? array() : $item['below'];
        break;
      }
    }
  }
  return supertheme_navigation_links_level($tree_page, $tree_all);
}


/**
* Helper function for supertheme_navigation_links to recursively create an array of links.
* (Both trees are required in order to include every menu item and active trail info.)
*/
function supertheme_navigation_links_level($tree_page, $tree_all) {
  $links = array();
  foreach ($tree_all as $key => $item) {
    $item_page = $tree_page[$key];
    $item_all = $tree_all[$key];
    if (!$item_all['link']['hidden']) {
      $l = $item_all['link']['localized_options'];
      $l['href'] = $item_all['link']['href'];
      $l['title'] = $item_all['link']['title'];
      if ($item_page['link']['in_active_trail']) {
        if (empty($l['attributes']['class'])) {
          $l['attributes']['class'] = 'active-trail';
        }
        else {
          $l['attributes']['class'] .= ' active-trail';
        }
      }
      if ($item_all['below']) {
        $l['children'] = supertheme_navigation_links_level($item_page['below'], $item_all['below']);
      }
      // Keyed with unique menu id to generate classes from theme_links().
      $links['menu-'. $item_all['link']['mlid']] = $l;
    }
  }
  return $links;
}
/**
* Return a themed set of links. (Extended to support multidimensional arrays of links.)
*/
function supertheme_links($links, $attributes = array('class' => 'links')) {
  $output = '';

  if (count($links) > 0) {
    $output = '<ul'. drupal_attributes($attributes) .'>';

    $num_links = count($links);
    $i = 1;

    foreach ($links as $key => $link) {
      $class = $key;

      // Add first, last and active classes to the list of links to help out themers.
      if ($i == 1) {
        $class .= ' first';
      }
      if ($i == $num_links) {
        $class .= ' last';
      }
      if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))) {
        $class .= ' active';
      }
      // Added: if the link has child items, add a haschildren class
      if (isset($link['children'])) {
        $class .= ' haschildren';
      }
      $output .= '<li'. drupal_attributes(array('class' => $class)) .'>';

      if (isset($link['href'])) {
        // Pass in $link as $options, they share the same keys.
        $output .= l($link['title'], $link['href'], $link);
      }
      else if (!empty($link['title'])) {
        // Some links are actually not links, but we wrap these in <span> for adding title and class attributes
        if (empty($link['html'])) {
          $link['title'] = check_plain($link['title']);
        }
        $span_attributes = '';
        if (isset($link['attributes'])) {
          $span_attributes = drupal_attributes($link['attributes']);
        }
        $output .= '<span'. $span_attributes .'>'. $link['title'] .'</span>';
      }

      // Added: if the link has child items, print them out recursively
      if (isset($link['children'])) {
        $output .= "\n" . theme('links', $link['children'], array());
      }

      $i++;
      $output .= "</li>\n";
    }

    $output .= '</ul>';
  }

  return $output;
}
function supertheme_primary_links() {
  return supertheme_navigation_links(variable_get('menu_primary_links_source', 'primary-links'

)); }

回答1:

3 comments:

  • Not totally sure what you meant when you said you tried to change $level to 0, but then it will not enter in the loop: while ($level-- > 0 && $tree_page)

  • To be able to stop a recursion, the recursive function needs to have an argument with the depth. So INSIDE the recursive function you decide when to stop: if ($depth <1) { return; } and everytime you call the recursive funcion you call it with $depth-1

  • If you want this functionality 'out-of-the-box', try http://drupal.org/project/menu_block , or get some inspiration from its code: (see menu_tree_depth_trim function)



回答2:

I believe, that if you set your menu to be non-expanded under menu settings that Drupal will handle the rest for you.

Another option would be to use nice menus which mainly is used to show expandable menus, but also can be used to control the level of menu expansion.



标签: drupal menu