WordPress Menu Custom Walker Class

The easiest way is to extend the Walker_Nav_Menu class rather than the Walker_Class, (as the parent / ID fields are set and often you want to maintain some of the mark-up etc).

The main methods are:

  • start_el / end_el – responsible for displaying an element in a list
  • start_lvl / end_lvl – responsible for displaying a sub menu

Also, there are walk and display_element which largely just control the mechanics of the class. For most purposes the above four functions are those that are needed to be altered in an extending class.

That said, the structure you are after isn’t really nested, so you aren’t really using the Walker Class to its full extent here. However this custom walker class will get you most of the way there:

class SH_Accordian_Walker extends Walker_Nav_Menu {  

    //Start 'sub menu'
    function start_lvl(&$output, $depth=0, $args=array()) {  

        if($depth > 0)
           return parent::end_lvl(&$output, $depth);

        $output .= '<div><ul>';
    }  

    //End 'sub menu'
    function end_lvl(&$output, $depth=0, $args=array()) {  
        if($depth > 0)
           return parent::end_lvl(&$output, $depth);

        $output .= '</ul></div>';
    }  

    // Start element
    function start_el(&$output, $item, $depth=0, $args=array()) {  
        if( 0 == $depth ){
             $output.= '<h2><a href="'.esc_attr($item->url).'">'.apply_filters( 'the_title', $item->title, $item->ID ).'</a></h2>';
             return; 
        }

        // level 2+
        parent::start_el(&$output, $item, $depth, $args);  
    }  

    // Don't need to add any output - sub menus aren't nested
    function end_el(&$output, $item, $depth=0, $args=array()) {
       if($depth > 0)
         parent::end_el(&$output, $item, $depth);
    }  

} 

This is just a very simply class to demonstrate what you need to do. Since your structure isn’t nested – this might not look right if we go down further than 2 levels (i.e. to grand-children).

Usage:

wp_nav_menu( array( 
       'theme_location' => 'primary',
       'walker'=> new SH_Accordian_Walker, 
       'depth'=>2,
       'items_wrap'=> '%3$s'
     ) );

(I’ve recently written this tutorial on the Walker Class: http://wp.tutsplus.com/tutorials/creative-coding/understanding-the-walker-class/ that you might find helpful)

Leave a Comment