How are people expanding links for instance in a sidebar? Let´s say I click a menu item in the navbar and I want to add the menu to a sidebar and expand all sibling menu items but have parent items collapsed.

There are discussion in the queue about what should be default and what not but I can´t find any suggestions on how to do this.

I´m using menu block without success because everything is collapsed by default, no matter how I fiddle with the settings in menu block. I guess Bootstrap overrides it.

Comments

busla’s picture

After playing with the menu_tree and menu_link hooks I´ve been able to change the collapse functionality somewhat but can´t get the the desired functionality to work.

Here are some examples from what I want to happen on my sidebar:
http://bootply.com/61710
http://jsfiddle.net/luismruiz/YRVev/

These are two fundamentally different methods, one is using accordion and the other a custom js script. Another way to accomplish this would be to use the menu collapse functionality in a mobile view.

I would appreciate if someone could post a suggestion on how to override the template hooks mentioned above.

Thanks.

busla’s picture

Ok, this took a while but I have found a solution that I´m very happy with (see theme_menu_link override below).

#Issue

My original issue was with horizontal menus on sidebars on pages that are visited. I also wanted an active trail to the page in the menu tree. I also wanted the menu tree to expand/collapse nicely using javascript, like so: http://bootply.com/63956

#Solution

I decided to use the Menu Block module since it offers setting configuration in the UI and some nice hooks to alter any menu on the sidebar. I´m also using Special Menu Items to create parent menu items since Bootstrap has a click dropdown menu instead of hover (which I like very much).

By using the theme_menu_link__[menu name] hook I altered the Bootstrap menu wrapper and added the neccesary classes required by the javascript.

The javascript didn´t want any text to be wrapped with tag that is applied by Special Menu Items so I needed to remove the tag before dumping the output to the l(); function (see the if statement at the end).

This is the altered code originally taken from the bootstrap_menu_link() function in includes/theme.inc
------

function mytheme_menu_link__menu_block(&$variables) {
  $element = $variables['element'];
  $sub_menu = '';
  
  if ($element['#below']) {

    // Prevent dropdown functions from being added to management menu as to not affect navbar module.
    if (($element['#original_link']['menu_name'] == 'management') && (module_exists('navbar'))) {
      $sub_menu = drupal_render($element['#below']);
    }

    else {
      // Add our own wrapper
      
      unset($element['#below']['#theme_wrappers']);
      $sub_menu = '<ul class="nav nav-list tree">' . drupal_render($element['#below']) . '</ul>';
     //  $element['#localized_options']['attributes']['class'][] = 'nav nav-list tree';
      // $element['#localized_options']['attributes']['data-toggle'] = 'dropdown';

      // Check if this element is nested within another
      if ((!empty($element['#original_link']['depth'])) && ($element['#original_link']['depth'] > 1)) {
        // Generate as dropdown submenu
        $element['#attributes']['class'][] = 'tree-toggler';
        $element['#attributes']['class'][] = 'nav-header';
        $element['#localized_options']['html'] = TRUE;
        $element['#title'] = '<label class="tree-toggler nav-header">' . $element['#title'] . '</label>';
        
      }
      else {
        // Generate as standard dropdown
        // $element['#attributes']['class'][] = 'dropdown';
        $element['#localized_options']['html'] = TRUE;
        $element['#title'] = '<label class="tree-toggler nav-header">' . $element['#title'] . '</label>';
      }
      
      // Set dropdown trigger element to # to prevent inadvertant page loading with submenu click
      // $element['#localized_options']['attributes']['data-target'] = '#';
    }
  }
 // Issue #1896674 - On primary navigation menu, class 'active' is not set on active menu item.
 // @see http://drupal.org/node/1896674
 if (($element['#href'] == $_GET['q'] || ($element['#href'] == '<front>' && drupal_is_front_page())) && (empty($element['#localized_options']['language']) || $element['#localized_options']['language']->language == $language_url->language)) {
   $element['#attributes']['class'][] = 'active';
 }

  if (strpos( $element['#href'], 'nolink')) {
      $output = $element['#title'];
    }
  else {  
    $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  }
//   dpm($element);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
busla’s picture

Ok, you can obviously just remove the nesting condition if you like since it makes no sense now :-)

function mytheme_menu_link__menu_block(&$variables) {
  $element = $variables['element'];
  $sub_menu = '';
  
  if ($element['#below']) {

    // Prevent dropdown functions from being added to management menu as to not affect navbar module.
    if (($element['#original_link']['menu_name'] == 'management') && (module_exists('navbar'))) {
      $sub_menu = drupal_render($element['#below']);
    }

    else {
      // Add our own wrapper
      
      unset($element['#below']['#theme_wrappers']);
      $sub_menu = '<ul class="nav nav-list tree">' . drupal_render($element['#below']) . '</ul>';
  
        $element['#localized_options']['html'] = TRUE;
        $element['#title'] = '<label class="tree-toggler nav-header">' . $element['#title'] . '</label>';

    }
  }
 // Issue #1896674 - On primary navigation menu, class 'active' is not set on active menu item.
 // @see http://drupal.org/node/1896674
 if (($element['#href'] == $_GET['q'] || ($element['#href'] == '<front>' && drupal_is_front_page())) && (empty($element['#localized_options']['language']) || $element['#localized_options']['language']->language == $language_url->language)) {
   $element['#attributes']['class'][] = 'active';
 }

  if (strpos( $element['#href'], 'nolink')) {
      $output = $element['#title'];
    }
  else {  
    $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  }
//   dpm($element);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
busla’s picture

I still haven´t figured out why all parent menu items expand all children by default so if anyone wants to help out it would be appreciated :-)

busla’s picture

oops.. posted the wrong link to the javascript code i´m using. They seem to be the same except the class names are different.

http://cssdeck.com/labs/twitter-bootstrap-plain-collapsible-tree-menu

geresy’s picture

Thank you very much busla !

Took me a few good hours of trying on my own until i found your solution ! #2 works like a charm combined with the module Menu Firstchild.

busla’s picture

Menu Firstchild, guess I have to check out that module!

Thanks for posting :-)

markhalliwell’s picture

Issue summary: View changes
Status: Active » Closed (won't fix)

This issue has been closed while cleaning up the issue queue. The 7.x-2.x branch currently only receives security fixes.