3

I am trying to build a Wordpress theme with boostrap, but the nav menu is giving me some trouble. I would like the dropdown to work like boostraps dropdown, but I do not know how to do this.

This is my menu:

<ul class="nav">
   <?php wp_nav_menu( array( 'items_wrap' => '%3$s' ) ); ?>
</ul>

This is what I have in my functions.php for the menu:

add_action('after_setup_theme', 'blankslate_setup');
function blankslate_setup(){
register_nav_menus(
array( 'main-menu' => __( 'Main Menu', 'blankslate' ) )
);
}

function my_wp_nav_menu_args( $args = '' )
{
    $args['container'] = false;
    return $args;
} // function

add_filter( 'wp_nav_menu_args', 'my_wp_nav_menu_args' );

When I add a submenu item (via Appearance - Menus) this is what is currently generated:

<ul class="nav">
    <li id="menu-item-18" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-18"><a href="#">Parent</a>
        <ul class="sub-menu">
                <li id="menu-item-19" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-19"><a href="#">Child</a></li>
        </ul>
    </li>
</ul>

For my menu to work with bootstrap I need the menu to be generated like:

<ul class="nav">
    <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Parent <b class="caret"></b></a>
        <ul class="dropdown-menu">
            <li><a href="#">Child</a></li>
        </ul>
    </li>
</ul>

So I need:

  • To add the class "dropdown", if a menu-item has child-items.
  • To add class="dropdown-toggle" data-toggle="dropdown" to the .dropdown a element
  • To add <b class="caret"></b> after the Dropdown-menu name (inside the .dropdown a element)
  • To add class="dropdown-menu" to <ul class="sub-menu">

Hope someone can help!

  • If you search on Github, you'll find some custom walker functions for wp_nav_menu on Bootstrap. – RRikesh Feb 27 '13 at 9:28
5

You will need to write a custom walker extending Walker_Nav_Menu, more or less like so:

class My_Custom_Nav_Walker extends Walker_Nav_Menu {

   function start_lvl(&$output, $depth = 0, $args = array()) {
      $output .= "\n<ul class=\"dropdown-menu\">\n";
   }

   function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
       $item_html = '';
       parent::start_el($item_html, $item, $depth, $args);

       if ( $item->is_dropdown && $depth === 0 ) {
           $item_html = str_replace( '<a', '<a class="dropdown-toggle" data-toggle="dropdown"', $item_html );
           $item_html = str_replace( '</a>', ' <b class="caret"></b></a>', $item_html );
       }

       $output .= $item_html;
    }

    function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
        if ( $element->current )
        $element->classes[] = 'active';

        $element->is_dropdown = !empty( $children_elements[$element->ID] );

        if ( $element->is_dropdown ) {
            if ( $depth === 0 ) {
                $element->classes[] = 'dropdown';
            } elseif ( $depth === 1 ) {
                // Extra level of dropdown menu, 
                // as seen in http://twitter.github.com/bootstrap/components.html#dropdowns
                $element->classes[] = 'dropdown-submenu';
            }
        }

    parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
    }
}

Not sure of what you need with points 3 and 4, though.

  • Thank you, I will try it out. I forgot to wrap some code in point 3 and 4 :) – Cody Feb 27 '13 at 10:27
  • Ok, now it makes sense, I think the above code should take care of it all. – Sunyatasattva Feb 27 '13 at 10:38
  • do you think there would be a way to do this in the functions.php? Or in some other way which would allow me to only modify the theme. – Cody Feb 27 '13 at 10:49
  • You can totally use this in your functions.php, perhaps use an include to an external file to keep it a bit cleaner, but that's all. – Sunyatasattva Feb 27 '13 at 11:55
  • Thank you! You saved the day, it is working like a charm :) – Cody Feb 27 '13 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.