0
votes

How would one write a block hook that renders a custom menu depending on the current URL, with the active trail applied? I cannot do it with a regular menus, since they are cached. With custom I mean different menu items for different users.

An example menu could look like this when looking at Users X's profile

|-- User X's profile (active)
|-- User X's groups
    |-- Group A
    |-- Group B
    |-- Group C

But if I browse to my own user profile, go to settings, the menu might look like this

|-- My profile
|-- My settings
    |-- Profile settings (active)
    |-- Group settings
|-- My groups
    |-- Group X
    |-- Group Y
    |-- Group Z

It would be very easy to just create a block that outputs this in plain HTML. But as said above, I need the active-trail applied on the links. And I also only want to edit the routes from the different menu hooks, not hard code or anything similar.

Any suggestions?

1

1 Answers

0
votes

I don't remember where I stole this from, but if you call 'your_module_menu_tree_full()' you will get the named menu as an array-tree with the active item annotated.

function your_module_menu_tree_full($menu_name = 'main-menu') {
  static $menu_output = array();
  if (!isset($menu_output[$menu_name])) {
    $tree = _your_module__menu_find_active_trail(menu_tree_all_data($menu_name));
    $menu_output[$menu_name] = menu_tree_output($tree);
  }
  return $menu_output[$menu_name];
}

function _your_module__menu_find_active_trail(&$menu_tree) {
  $item = menu_get_item();
  _your_module_menu_find_active_trail($menu_tree, $item);
  return $menu_tree;
}

function _your_module_menu_find_active_trail(&$menu_tree, $item) {
  $level_is_expanded = FALSE;
  foreach($menu_tree as &$menu_item) {
    $link = &$menu_item['link'];
    if ($link['href']==$item['href']) { // Found the exact location in the tree
      $link['active'] = TRUE;
      $link['in_active_trail'] = TRUE;
      return true;
    } else {
      if ($link['has_children']) {
        $result = _your_module_menu_find_active_trail($menu_item['below'], $item);
        $link['in_active_trail'] = $result;
        if ($result) $level_is_expanded = TRUE;
      }
    }
  }
  return $level_is_expanded;
}

Try:

$menu = your_module_menu_tree_full('main-menu');
error_log(print_r($menu, TRUE));