I have created a custom walker class for changing the output of menu items. Where do I place my custom walker class file at? I have tried to ask on the Wordpress forum but it has gone 3 days with no response.

I have already created the class. I just don't know where to physically put the code. Does it go in the existing class-wp-walker.php file or do I need to create my own file somewhere?

Thank you much!

  • So open your functions.php file and place class – Vasim Shaikh Feb 17 '16 at 18:32
  • Or add it in menu_walker.php and include that file in your functions.php in a function that you'll hook to after_setup_theme. A lot cleaner than to crowd your functions.php file ;) – dingo_d Feb 17 '16 at 18:43

The walker class is an abstract class designed to help traverse and display elements which have a hierarchical (or tree like) structure. It doesn't actually 'do' (in the sense of generating HTML) anything.

in your template files, we will use the wp_nav_menu() function twice, pointing to the same theme location (I shall call it 'primary'). If you don't have a theme location registered already you should read this article. Whichever theme location you are using, you should save a menu to that location. We shall display this menu twice. First, wherever you want your 'top-level' menu to appear:

wp_nav_menu( array('theme_location'=>'primary','depth' => 1) );

Then again, with a custom walker, to display only the (relevant) child pages.

wp_nav_menu( array('theme_location'=>'primary','walker' => new SH_Child_Only_Walker(),'depth' => 0) );

I follow this example :

class SH_Child_Only_Walker extends Walker_Nav_Menu {

    // Don't start the top level
    function start_lvl(&$output, $depth=0, $args=array()) {
        if( 0 == $depth )
        parent::start_lvl(&$output, $depth,$args);

    // Don't end the top level
    function end_lvl(&$output, $depth=0, $args=array()) {
        if( 0 == $depth )
        parent::end_lvl(&$output, $depth,$args);

    // Don't print top-level elements
    function start_el(&$output, $item, $depth=0, $args=array()) {
        if( 0 == $depth )
        parent::start_el(&$output, $item, $depth, $args);

    function end_el(&$output, $item, $depth=0, $args=array()) {
        if( 0 == $depth )
        parent::end_el(&$output, $item, $depth, $args);

    // Only follow down one branch
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {

        // Check if element as a 'current element' class
        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );
        $current_class = array_intersect( $current_element_markers, $element->classes );

        // If element has a 'current' class, it is an ancestor of the current element
        $ancestor_of_current = !empty($current_class);

        // If this is a top-level link and not the current, or ancestor of the current menu item - stop here.
        if ( 0 == $depth && !$ancestor_of_current)

        parent::display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output );
| improve this answer | |

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.