Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Extended Walker class for use with the Twitter Bootstrap toolkit Dropdown menus in Wordpress.
<?php
add_action( 'after_setup_theme', 'bootstrap_setup' );
if ( ! function_exists( 'bootstrap_setup' ) ):
function bootstrap_setup(){
add_action( 'init', 'register_menu' );
function register_menu(){
register_nav_menu( 'top-bar', 'Bootstrap Top Menu' );
}
class Bootstrap_Walker_Nav_Menu extends Walker_Nav_Menu {
function start_lvl( &$output, $depth ) {
$indent = str_repeat( "\t", $depth );
$output .= "\n$indent<ul class=\"dropdown-menu\">\n";
}
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$li_attributes = '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = ($args->has_children) ? 'dropdown' : '';
$classes[] = ($item->current || $item->current_item_ancestor) ? 'active' : '';
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
$class_names = ' class="' . esc_attr( $class_names ) . '"';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names . $li_attributes . '>';
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
$attributes .= ($args->has_children) ? ' class="dropdown-toggle" data-toggle="dropdown"' : '';
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= ($args->has_children) ? ' <b class="caret"></b></a>' : '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
if ( !$element )
return;
$id_field = $this->db_fields['id'];
//display this element
if ( is_array( $args[0] ) )
$args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
else if ( is_object( $args[0] ) )
$args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
$cb_args = array_merge( array(&$output, $element, $depth), $args);
call_user_func_array(array(&$this, 'start_el'), $cb_args);
$id = $element->$id_field;
// descend only when the depth is right and there are childrens for this element
if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {
foreach( $children_elements[ $id ] as $child ){
if ( !isset($newlevel) ) {
$newlevel = true;
//start the child delimiter
$cb_args = array_merge( array(&$output, $depth), $args);
call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
}
$this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
}
unset( $children_elements[ $id ] );
}
if ( isset($newlevel) && $newlevel ){
//end the child delimiter
$cb_args = array_merge( array(&$output, $depth), $args);
call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
}
//end this element
$cb_args = array_merge( array(&$output, $element, $depth), $args);
call_user_func_array(array(&$this, 'end_el'), $cb_args);
}
}
}
endif;
?>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<?php
$args = array(
'theme_location' => 'top-bar',
'depth' => 2,
'container' => false,
'menu_class' => 'nav',
'walker' => new Bootstrap_Walker_Nav_Menu()
);
wp_nav_menu($args);
?>
</div>
</div>
</div>
@jimmyrosen

sweet!

@martajohnsson

Hello, I can't get it work:-(

@hellquist

Cheers for this. :)

@ivanfgautama

it works for 2 level of dropdown, but more than 2 level it doesnt seem to work,

@yourdesigncoza

THX, saved me couple of hours coding

@Alipio123

can we make this to unlimited level of dropdown menu?

because currently @ ivanfgautama "it works for 2 level of dropdown "

@AdamKyle

@Alipio123 set the depth in the args array to 0 and there ya fo

@tszming

One of the minor issue is the menu is not fully responsive, e.g. still presenting a layer on dropdown items on mobile devices (as compared to http://320press.com/wpbs/), but anyway, it is really a nice snippet and get the job done.

Thanks!

@shprink

Good job dude!

@seomezshiva

awesome job bro I like to implement this tutorial in SEOmez.com within few days...!!!

@larsemil

Awesome! Saved me alot of work.

Allthough i dont get it to expand beyond second level('when having another dropdown in the first').
Any hints on what to do?

Here is my wp_nav_code:

               $args = array(
                    'theme_location' => 'top-bar',
                    'depth'      => 0,
                    'container'  => false,
                    'menu_class'     => 'nav',
                    'walker'     => new Bootstrap_Walker_Nav_Menu()
                );  

                wp_nav_menu($args);
@maronl

uhm ... I'm doing my first work on Wordpress and so I'm still learning. I cannot make the extends Walker_Nav_Menu working as described above. if I try the code (but also all the other codes I found extending Wlaker_Nav_Menu) the result is an empty bullet list without any text/reference and also without sub-levels. something like

<div class="nav">
<ul>
<li class="menu-item-10" id="menu-item-10"><a></a></li>
<li class="menu-item-2" id="menu-item-2"><a></a></li>
<li class="menu-item-4" id="menu-item-4"><a></a></li>
</ul>
</div>

some tip to sort this out?

@thepauleh

Are you setting the menu in the Wordpress Admin? When you only create the menu Wordpress falls back to a different menu function - you just need to tell it where to put each menu.

I can't figure out how to do this markdown stuff but basically for responsive:
button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"
span class="icon-bar">/span
span class="icon-bar">/span
span class="icon-bar">/span
/button
div class='nav-collapse collapse'
wp_nav_menu....
/div

@chrispaynter

Great job man, this really saved me some time. Thanks.

@cynthusia

I am having the same issue as lukennon. I switched from my custom theme to an untouched install of the "wordpress-bootstrap" theme to test and it still happens. I have tried:

'theme_location' => 'primary',

as well as the menu ID# and menu name and slug. But I still just get an empty bulleted list as described in lukennon's comment.

Just to confirm, I am supposed to replace what's in my functions.php from this comment // Menu output mods, to just before the line that says add_editor_style('editor-style.css'); ?

@borisgw

Wow this is great, would buy you a beer if have international visa :P

@jyoseph

Kick ass, thanks so much for this.

@MobsterGit

I'm having issues with https. Any suggestions to remove the http:// from the menu? Thanks!

@richardmax

Had the same issue as cynthusia and lukennon (+ hundreds of similar devs in other forums) - it was Appearance > Menu wasn't set! Duurrgggh but good to know....

@lwensveen

Does anybody have a version that works with bootstrap 3 rc?

@joelalejandro

I've made this work perfectly with Bootstrap 3.0.0. Thanks John!

@tommusrhodus

Cheers John! Saved me a couple of hours, much appreciated!

@sebastienb

Is there a way to make it work on mouse over to retain the function of the top level link ?

@apsolut

3level - i got it working like this

//use Johns code and plus this jquery..

jQuery(".dropdown-menu li.dropdown-toggle").on("mouseenter", function () {

 jQuery(this).find( ".dropdown-menu").css({ "display": "block" }, "slow" );

}).on("mouseleave", function () {

jQuery(this).find( ".dropdown-menu").css({ "display": "none" }, "slow" );

});
@rbfuertes

Good day Sir. my problem is notactive menu on 2 page the Home, and blog but the rest is active the about-us contact etc. The home is front-page.php and blog is index,php Thanks in advance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.