You are here

function menu_block_tree_output in Menu Block 7.2

Same name and namespace in other branches
  1. 6.2 menu_block.module \menu_block_tree_output()
  2. 7.3 menu_block.module \menu_block_tree_output()

Returns a renderable menu tree.

This is a copy of menu_tree_output() with additional classes added to the output.

Parameters

array $tree: A data structure representing the tree as returned from menu_tree_data.

array $config:

Return value

array The menu tree as a render array.

1 call to menu_block_tree_output()
menu_tree_build in ./menu_block.module
Build a menu tree based on the provided configuration.

File

./menu_block.module, line 802
Provides configurable blocks of menu items.

Code

function menu_block_tree_output(array &$tree, array $config = array()) {
  $build = array();
  $items = array();

  // Create context if no config was provided.
  if (empty($config)) {
    $config['delta'] = 0;

    // Grab any menu item to find the menu_name for this tree.
    $menu_item = current($tree);
    $config['menu_name'] = $menu_item['link']['menu_name'];
  }
  $hook_delta = str_replace('-', '_', $config['delta']);
  $hook_menu_name = str_replace('-', '_', $config['menu_name']);

  // Pull out just the menu links we are going to render so that we
  // get an accurate count for the first/last classes.
  foreach ($tree as $key => &$value) {
    if ($tree[$key]['link']['access'] && !$tree[$key]['link']['hidden']) {
      $items[] = $tree[$key];
    }
  }
  $router_item = menu_get_item();
  $num_items = count($items);
  foreach ($items as $i => &$data) {
    $class = array();
    if ($i == 0) {
      $class[] = 'first';
    }
    if ($i == $num_items - 1) {
      $class[] = 'last';
    }

    // Set a class for the <li>-tag. Since $data['below'] may contain local
    // tasks, only set 'expanded' class if the link also has children within
    // the current menu.
    if ($data['link']['has_children'] && $data['below']) {
      $class[] = 'expanded';
    }
    elseif ($data['link']['has_children']) {
      $class[] = 'collapsed';
    }
    else {
      $class[] = 'leaf';
    }
    if (!empty($data['link']['leaf_has_children'])) {
      $class[] = 'has-children';
    }

    // Set a class if the link is in the active trail.
    if ($data['link']['in_active_trail']) {
      $class[] = 'active-trail';
      $data['link']['localized_options']['attributes']['class'][] = 'active-trail';
    }
    if ($data['link']['href'] == $_GET['q'] || $data['link']['href'] == '<front>' && drupal_is_front_page()) {
      $class[] = 'active';
    }

    // Set a menu link ID class.
    $class[] = 'menu-mlid-' . $data['link']['mlid'];

    // Normally, l() compares the href of every link with $_GET['q'] and sets
    // the active class accordingly. But local tasks do not appear in menu
    // trees, so if the current path is a local task, and this link is its
    // tab root, then we have to set the class manually.
    if ($router_item && $data['link']['href'] == $router_item['tab_root_href'] && $data['link']['href'] != $_GET['q']) {
      $data['link']['localized_options']['attributes']['class'][] = 'active';
    }

    // Allow menu-specific theme overrides.
    $element['#theme'] = array(
      'menu_link__menu_block__' . $hook_delta,
      'menu_link__menu_block__' . $hook_menu_name,
      'menu_link__menu_block',
      'menu_link__' . $hook_menu_name,
      'menu_link',
    );
    $element['#attributes']['class'] = $class;
    $element['#title'] = $data['link']['title'];
    $element['#href'] = $data['link']['href'];
    $element['#localized_options'] = !empty($data['link']['localized_options']) ? $data['link']['localized_options'] : array();
    $element['#below'] = $data['below'] ? menu_block_tree_output($data['below'], $config) : $data['below'];
    $element['#original_link'] = $data['link'];
    $element['#bid'] = array(
      'module' => 'menu_block',
      'delta' => $config['delta'],
    );

    // Index using the link's unique mlid.
    $build[$data['link']['mlid']] = $element;
  }
  if ($build) {

    // Make sure drupal_render() does not re-order the links.
    $build['#sorted'] = TRUE;

    // Add the theme wrapper for outer markup.
    // Allow menu-specific theme overrides.
    $build['#theme_wrappers'][] = array(
      'menu_tree__menu_block__' . $hook_delta,
      'menu_tree__menu_block__' . $hook_menu_name,
      'menu_tree__menu_block',
      'menu_tree__' . $hook_menu_name,
      'menu_tree',
    );
  }
  return $build;
}