Hi,

I would like to know how to hide menu block if some active trail have no children. I explain :
My main menu tree is someting like :

- A
- A.1
- A.1.1
- A.1.2
- A.2

- B
- B.1
- B.2
- B.2.1
- B.2.2

I configure menu block to start at level 1 so, when I'm on A1, the menu block is :
- A.1
- A.1.1
- A.1.2
- A2

But when I'm on A2, it is :
- A1
- A2

Because A2 has no clidren, I don't want to display the menu block. How can I do ?
By the way, is there an option to hide siblings too (don't show A2 when I'm on the A1 trail).

Thank you for your help.

Comments

dcanetma’s picture

Hola,

I think I found a solution for this.

On your module, use this hook:

/**
 * Implements: hook_menu_block_tree_alter
 *
 * Alter the menu tree and its configuration before the tree is rendered.
 *
 * @param $tree
 *   An array containing the unrendered menu tree.
 * @param $config
 *   An array containing the configuration of the tree.
 */
function <your_module_name>_menu_block_tree_alter(&$tree, &$config) {
  module_load_include('inc', 'menu_block', 'menu_block.follow');
  $original_tree = $tree;
  _<your_module_name>_menu_tree_prune_active_tree($tree, 'child');
  if ($tree == $original_tree)
  {
    $tree = array();
  }
}
/**
 * Prune a tree so that it begins at the active menu item.
 *
 * @param $tree
 *   array The menu tree to prune.
 * @param $level
 *   string The level which the tree will be pruned to: 'active' or 'child'.
 * @return
 *   void
 */
function _<your_module_name>_menu_tree_prune_active_tree(&$tree, $level) {
  do {
    $found_active_trail = FALSE;
    // Examine each element at this level for the active trail.
    foreach ($tree AS $key => &$value) {
      if ($tree[$key]['link']['in_active_trail']) {
        $found_active_trail = TRUE;
        // If the active trail item has children, examine them.
        if ($tree[$key]['below']) {
          // If we are pruning to the active menu item's level, check if this
          // is the active menu item by checking its children.
          if ($level == 'active') {
            foreach ($tree[$key]['below'] AS $child_key => &$value) {
              if ($tree[$key]['below'][$child_key]['link']['in_active_trail']) {
                // Get the title for the pruned tree.
                menu_block_set_title($tree[$key]['link']);
                $tree = $tree[$key]['below'];
                // Continue in the pruned tree.
                break 2;
              }
            }
            // If we've found the active item, we're done.
            break 2;
          }
          // Set the title for the pruned tree.
          menu_block_set_title($tree[$key]['link']);
          // If we are pruning to the children of the active menu item, just
          // prune the tree to the children of the item in the active trail.
          $tree = $tree[$key]['below'];
          // Continue in the pruned tree.
          break;
        }
        // If the active menu item has no children, we're done.
        else {
          if ($level == 'child') {
            $tree = array();
          }
          break 2;
        }
      }
    }
  } while ($found_active_trail);
}

I hope it helps @jofdesign.

Cheers,

D.

JoshaHubbers’s picture

A little late reaction, but for the record... ;-).

The idea is ok, but the main problem is that the module is not implementing this the right way:
See #3199909: _menu_tree_prune_active_tree level is passed wrong parameter.

You can also use:

/**
 * Implements: hook_menu_block_tree_alter
 *
 * Alter the menu tree and its configuration before the tree is rendered.
 *
 * @param $tree
 *   An array containing the unrendered menu tree.
 * @param $config
 *   An array containing the configuration of the tree.
 */
function <your_module_name>_menu_block_tree_alter(&$tree, &$config) {
  module_load_include('inc', 'menu_block', 'menu_block.follow');
  _menu_tree_prune_active_tree($tree, 'active');
}