Tag Archives: walker

Update #2: Using Twitter Bootstrap Dropdown Menus with WordPress

 

02/17/12 – Updated! Click here for the latest code. After some testing, there were a few fixed to clean up the HTML.

02/13/12 – This code has been updated to work with Twitter Bootstrap 2.0. Click here to see the latest update.

 


Okay, third time is a charm? After finding a trac ticket for the missing has_children parameter here, I’ve made some changes that get the previous extended walker class that I posted working in more (hopefully all) situations. In WordPress 3.4, this should be fixed and rewriting the display_element function shouldn’t be necessary.

The problem with the previous post was that it relied on last_query containing the menu query. I thought that because the menu functions were still running, the menu query would logically be the last query run. This was true on one test theme, but not on another.

Get the gist – https://gist.github.com/1597994

class Bootstrap_Walker_Nav_Menu extends Walker_Nav_Menu {

	function start_lvl( &$output, $depth ) {

		//In a child UL, add the 'dropdown-menu' class
		$indent = str_repeat( "\t", $depth );
		$output	   .= "\n$indent</pre>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">\n";</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$li_attributes = '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$class_names = $value = '';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$classes = empty( $item->classes ) ? array() : (array) $item->classes;</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//Add class and attribute to LI element that contains a submenu UL.</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">if ($args->has_children){</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$classes[] = 'dropdown';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$li_attributes .= 'data-dropdown="dropdown"';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$classes[] = 'menu-item-' . $item->ID;</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//If we are on the current page, add the active class to that menu item.</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$classes[] = ($item->current) ? 'active' : '';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//Make sure you still add all of the WordPress classes.</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$class_names = ' class="' . esc_attr( $class_names ) . '"';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$output .= $indent . '';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//Add attributes to link element.</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$attributes .= ($args->has_children) ? ' class="dropdown-toggle"' : '';</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$item_output = $args->before;</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$item_output .= '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$item_output .= '';</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$item_output .= $args->after;</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//Overwrite display_element function to add has_children attribute. Not needed in >= WordPress 3.4</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">if ( !$element )</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">return;</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$id_field = $this->db_fields['id'];</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//display this element</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">if ( is_array( $args[0] ) )</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">else if ( is_object( $args[0] ) )</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$args[0]->has_children = ! empty( $children_elements[$element->$id_field] );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$cb_args = array_merge( array(&$output, $element, $depth), $args);</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">call_user_func_array(array(&$this, 'start_el'), $cb_args);</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$id = $element->$id_field;</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">// descend only when the depth is right and there are childrens for this element</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">foreach( $children_elements[ $id ] as $child ){</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">if ( !isset($newlevel) ) {</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$newlevel = true;</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//start the child delimiter</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$cb_args = array_merge( array(&$output, $depth), $args);</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">call_user_func_array(array(&$this, 'start_lvl'), $cb_args);</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">unset( $children_elements[ $id ] );</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">if ( isset($newlevel) && $newlevel ){</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//end the child delimiter</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$cb_args = array_merge( array(&$output, $depth), $args);</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">call_user_func_array(array(&$this, 'end_lvl'), $cb_args);</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">//end this element</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">$cb_args = array_merge( array(&$output, $element, $depth), $args);</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">call_user_func_array(array(&$this, 'end_el'), $cb_args);</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
<ul class="\&quot;dropdown-menu\&quot;">
<ul class="\&quot;dropdown-menu\&quot;">}</ul>
</ul>
&nbsp;
<ul class="\&quot;dropdown-menu\&quot;">
%d bloggers like this: