I have a single menu split into menu blocks like this Menu Level 1+, Menu Level 2+, Menu Level 3+. The first level is used as my site's main navigation menu at the top of the page, the second menu block appears in the content (within a panel) showing the children of level 1's active item as a secondary navigation. The 3rd level menu block appears in a panel node showing the children of level 2's active item.

The problem is that level 1 and level 2 menu blocks are showing correctly however level 3 does not. It seems that the active trail stops at the second level menu block and i'm wondering if this is a problem with panels or something i've done wrong.

Comments

JohnAlbin’s picture

Category: bug » support
Status: Active » Closed (cannot reproduce)
lmeurs’s picture

Version: 7.x-2.2 » 7.x-2.7
Issue summary: View changes

I sort of am experiencing the same. Menu item trails in menu blocks inside a Panels pane do not always have .active and .active-trail classes, though menu items in the same menu block inside a standard Drupal region do.

I use Ctools Page Manager + Panels to override taxonomy/term/% pages. A menu built by Taxonomy Menu with product categories is displayed inside a Panel pane on the left and also in a standard Drupal footer region. The same setup is used to display product node pages.

When visiting a Product Category taxonomy term page, all menu items are activated as expected. To set an active menu trail for nodes so their corresponding product category menu items are activated, I used something like:

/**
 * Implements hook_preprocess_page().
 */
function mytheme_preprocess_page(&$variables) {
  // If current page is a node page, get the node.
  if ($node = menu_get_object('node', 1)) {
    // If the node has a Product Category taxonomy term reference.
    if ($field_product_category_items = field_get_items('node', $node, 'field_product_category')) {
      // Get Product Category's first field's value.
      $field_product_category_value = field_view_value('node', $node, 'field_product_category', $field_product_category_items[0]);
      // Set active path.
      menu_tree_set_path('my-menu', $field_product_category_value['#href']);
    }
  }
}

This does work for menu blocks in default Drupal regions, but not for menu blocks inside Panel panes. This probably has to do with the pane being rendered before the blocks and before the hook_preprocess_page() implementation which sets the active menu trail. After trying many other hooks, there seem two workarounds:

  1. An implementation of hook_menu_block_tree_alter() which is called whenever a menu block is being generated. This implementation sets the active menu trail and calls Menu Block's menu_tree_add_active_path() to activate the right menu items.
  2. An implementation of hook_init(), but this would also be called on pages that do not contain any menu block.
/**
 * Implements hook_menu_block_tree_alter().
 *
 * On product node pages we want to set the active menu trail using according to
 * Product Category taxonomy terms by calling menu_tree_set_path() from ie.
 * hook_preprocess_page(). This does work for Menu Block menu's inside default
 * Drupal regions, but not when the menu's remain inside a Panels pane which
 * seem rendered in an early stage.
 *
 * Two workarounds: call menu_tree_set_path() from hook_init() for each page or
 * from hook_menu_block_tree_alter() whenever a menu block is being generated.
 * 
 * @see menu_tree_block_data()
 */
function mytheme_menu_block_tree_alter(&$tree, &$config) {
  static $processed;

  // If current page is a node page, get the node.
  if (!isset($processed) && $node = menu_get_object('node', 1)) {
    // Update processed flag.
    $processed = TRUE;

    // If the node has a Product Category taxonomy term reference.
    if ($field_product_category_items = field_get_items('node', $node, 'field_product_category')) {
      // Get Product Category's first field's value.
      $field_product_category_value = field_view_value('node', $node, 'field_product_category', $field_product_category_items[0]);
      // Set active path.
      menu_tree_set_path('my-menu', $field_product_category_value['#href']);
      // And add the active trail data back to the full tree.
      menu_tree_add_active_path($tree);
    }
  }
}
capysara’s picture

#2 hook_menu_block_tree_alter worked for me. Thanks!