Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

WordPress From Bootstrap to WordPress Setup a Bootstrap Theme Creating Bootstrap Navigation in WordPress

Mike Bronner
Mike Bronner
16,395 Points

How To: Use Bootstrap "active" Class in Nav Menu

As @ZacGordon mentioned in the video, to take advantage of the more complex menu structure that Bootstrap provides, additional work that is outside of the scope of the lesson is necessary. This is my attempt at completing that exercise. Please let me know how you get along with it, or where improvements can be made.

/******************************************************************************
 * Enable Bootstrap Active Class In Navigation Menu
 *****************************************************************************/
class Bootstrap_Walker_Nav_Menu extends Walker_Nav_Menu
{
    function start_lvl( &$output, $depth = 0, $args = array() )
    {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu dropdown-menu\">\n";
    }

    function display_element ($element, &$children_elements, $max_depth, $depth = 0, $args, &$output)
    {
        $element->hasChildren = isset($children_elements[$element->ID]) && !empty($children_elements[$element->ID]);

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

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;
        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        if($item->current || $item->current_item_ancestor || $item->current_item_parent){
            $class_names .= ' active';
        }
        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
        $output .= $indent . '<li' . $id . $class_names .'>';
        $atts = array();
        $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
        $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
        $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
        $atts['href']   = ! empty( $item->url )        ? $item->url        : '';
        $atts['class']  = ($item->hasChildren)         ? 'dropdown-toggle' : '';
        $atts['data-toggle']  = ($item->hasChildren)   ? 'dropdown'        : '';
        $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
        $attributes = '';
        foreach ( $atts as $attr => $value ) {
            if ( ! empty( $value ) ) {
                $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }
        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        if( $item->hasChildren) {
            $item_output .= ' <b class="caret"></b>';
        }
        $item_output .= '</a>';
        $item_output .= $args->after;
        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}

Then update the wp_nav_menu() function in your header.php file as follows:

        <div class="navbar-collapse collapse">
            <?php
            wp_nav_menu(array(
                'menu' => 'header-menu',
                'menu_class' => 'nav navbar-nav',
                'container' => 'false',
                'walker' => new Bootstrap_Walker_Nav_Menu()
            ));
            ?>
        </div>

This will retain the classes and attributes set natively by wordpress, while at the same time adding the necessary bootstrap classes for the nav menu, so that you can simply drop in any bootstrap theme. (Never ever hack bootstrap core css, otherwise you end up painting yourself in a corner.)

I almost did the same thing haha I was ready to start looking into this for you (copied over and everything) then I scrolled down and saw your comment lol :P

I'll go ahead and set that as the answer

Mike Bronner
Mike Bronner
16,395 Points

Hi Jerry,

Yea, this wasn't as much posed as a question, but as an answer to the problem. :) I haven't actually implemented the solution that Zac referred to on GitHub, because this has worked great so far. :)

~Mike

Oh! oops :)

1 Answer