1

What I have

Right now I have an old template in plain HTML. In there I use a custom Navigation menu built like this:

<div class="collapse navbar-collapse main-menu main-menu-1" id="main-menu">
   <ul class="nav navbar-nav">
      <li class="active dropdown">
         <a data-toggle="dropdown" href="#">Parent item 1</a>
         <ul class="dropdown-menu" role="menu">
            <li>
                <a href="#">Sub Item 1</a>
            </li>
            <li class="active">
                <a href="#">Sub Item 2</a>
            </li>
         </ul>
      </li>
      <li class="main-menu-separator"></li>
      <li>
         <a href="#">Parent item 2</a>
      </li>
   </ul>
</div>

What I need

Right now I need to output my Wordpress Navigation just like this. Including every class and data-toggle element and all the main-menu-seperator li elements.

I know, that I need to use a custom walker for this. But I really don't know how to start with this.

The problem

I never used custom walkers extending the Walker_Nav_Menu before. So if anyone can help me building my custom navigation, I really would appreciate it!

The next problem is, that I don't know how to set the class="active" on the li elements of the parent and the childs.

Thank you very much in advance!

UPDATE 1

I just tried things with my custom walker and I'm getting some results now.

What I need right now:

  • I only want to add the class "dropdown" to the parent li element, if the element has children.
  • I still need a way to add my separator li's after each menu element.
  • Still missing is the possibility to show an "active" state. I saw, that wp_nav_menu is already outputting some classes like "current-page-item" and "current-menu-item"

This is what my wp_nav_menu command looks like:

$defaults = array(
'theme_location'  => '',
'menu'            => '',
'container'       => 'div',
'container_class' => 'collapse navbar-collapse main-menu main-menu-1',
'container_id'    => 'main-menu',
'menu_class'      => 'nav navbar-nav',
'menu_id'         => '',
'echo'            => true,
'fallback_cb'     => 'wp_page_menu',
'before'          => '',
'after'           => '',
'link_before'     => '',
'link_after'      => '',
'items_wrap'      => '<ul class="%2$s">%3$s</ul>',
'depth'           => 2,
'walker'          => new FoxTransport_Walker()
);
wp_nav_menu( $defaults );

And this is how my walker looks right now:

class FoxTransport_Walker extends Walker_Nav_Menu {

// add classes to ul sub-menus
function start_lvl( &$output, $depth ) {
    // depth dependent classes
    $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
    $display_depth = ( $depth + 1); // because it counts the first submenu as 0
    $classes = array(
        'dropdown-menu'
        );
    $class_names = implode( ' ', $classes );

    // build html
    $output .= "\n" . $indent . '<ul class="' . $class_names . '" role="menu">' . "\n";
}

// add main/sub classes to li's and links
 function start_el( &$output, $item, $depth, $args ) {
    global $wp_query;
    $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent

    // depth dependent classes
    $depth_classes = array(
        ( $depth == 0 ? 'dropdown' : '' )
    );
    $depth_class_names = esc_attr( implode( ' ', $depth_classes ) );

    // passed classes
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

    // build html
    $output .= $indent . '<li class="' . $depth_class_names . ' ' . $class_names . '">';

    // link 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 .= ' data-toggle="dropdown"';

    $item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s',
        $args->before,
        $attributes,
        $args->link_before,
        apply_filters( 'the_title', $item->title, $item->ID ),
        $args->link_after,
        $args->after
    );

    // build html
    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
   }
}

UPDATE 2

I just solved one problem. I have my active class now. The solution for me now was to add some few line in jQuery where I get the wordpress classes and add my ones then like this:

$('.current-page-item').addClass('active');
$('.current-menu-item').addClass('active');
$('.current_page_parent').addClass('active');
$('.menu-item-has-children').addClass('dropdown');
$('.menu-item-has-children > a').attr('data-toggle','dropdown');

That means that the following questions still remain:

  • I don't know how to add my separator li's after each parent menu item expect the last one.

Your Answer

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

Browse other questions tagged or ask your own question.