[Drupal] How to Create Multi-level Responsive Drop Down Menu in Drupal using Bootstrap

July 04, 2018 - 10:36

I had a requirement to add a multi-level responsive drop down menu in a Zyxware theme. Please do refer the below reference links to know more about responsive themes and free Drupal themes. So for that I had to edit page.tpl.php, page--front.tpl.php, style.css, template.php etc.

First I added the following code to template.php of my theme. The steps that I followed here are,

  • Added the following code to the function themename__preprocess_page(&$vars) to make the menu as a tree.

    
        //Setting menu in a tree structure
        $main_menu_tree = menu_tree(variable_get('menu_main_links_source', 'main-menu'));
        $vars['main_menu'] =  $main_menu_tree;
        // Get the entire main menu tree
        $main_menu_tree = menu_tree_all_data('main-menu');
        // Add the rendered output to the $main_menu_expanded variable
        $vars['main_menu_expanded'] = menu_tree_output($main_menu_tree);
      
    
  • Added css class to main menu using the function,
    
      function themename_menu_tree__main_menu(&$vars) {        
      return '<ul class="nav navbar-nav">' . $vars['tree'] . '</ul>';
     }
     
    
  • Added css class to inner part of main menu using the function,
    
    function themename_menu_tree__main_menu_inner($vars) {	
        return '<ul class="dropdown-menu">' . $vars['tree'] . '</ul>';
    }
    
    
  • Added the following function to display the links in main menu tree,
    
      function themename_menu_link__main_menu($vars) {
       $element = $vars['element'];
       $sub_menu = '';
    
       if ($element['#below']) {
        foreach ($element['#below'] as $key => $val) {
          if (is_numeric($key)) {             
            $element['#below'][$key]['#theme'] = 'menu_link__main_menu_inner'; // 2 level <li>
          }
        }
        $element['#below']['#theme_wrappers'][0] = 'menu_tree__main_menu_inner';  // 2 level <ul>
        $sub_menu = drupal_render($element['#below']);
      }
      $output = l($element['#title'], $element['#href'], $element['#localized_options']);
    
      $element['#localized_options']['attributes']['class'][] = " dropdown-toggle ";
      $element['#localized_options']['attributes']['role'][] = "menu";
      $element['#localized_options']['attributes']['data-toggle'][] = "dropdown";
      $element['#localized_options']['attributes']['aria-expanded'][] = "true";  
      
      $output = l($element['#title'], $element['#href'], $element['#localized_options']);
      return '<li class="dropdown">' . $output . $sub_menu . '</li>';
     }
     
    
  • Added the following code to make inner <li> tag - links
    
        function themename_menu_link__main_menu_inner($vars) {
          $element = $vars['element'];
          $sub_menu = '';
    
          if ($element['#below']) {
            $sub_menu = drupal_render($element['#below']);
          }
    
          $output = l($element['#title'], $element['#href'], $element['#localized_options']);
    
          return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . '</li>\n';
         }
    
    

Then I added the code ' print render($main_menu); ' to the page.tpl and page--front.tpl for display menu with necessary <div> tag and css styles based on the theme that were downloaded from http://getbootstrap.com/components

References :

Get Drupal updates straight to your inbox

To prevent automated spam submissions leave this field empty.

Post your comments / questions

Thank you.
I was so shocked when I realized that the bootstrap theme did not have more than 2 levels of nav. Wow

Your code worked right away. I need to minimally re-work my theme, but it is all good.

this - '

\n';
should be this - '

';

I did not have to add this
' print render($main_menu); ' to the page.tpl and page--front.tpl