How does a minimal menu walker look like?

According to the docs of wp_nav_menu we can specify our own walker function. They suggest to copy the default one and modify it as needed. But to be honest, it is a bit too complicated for the to understand.

Could you please provide a minimal example of a custom menu walker?

Read More

Say, without sub menu items, without wrapping container, without all the classes applied by the default walker. Only one class, the .current-menu-item is important, of course. Also a way to specify the HTML element of menu items may be included.

Related posts

2 comments

  1. You could create a very simple walker, like this one. To detect the current item, inspect $item->current. It is TRUE for the current item only.

    I wouldn’t add a class, but deactivate the useless link completely, because it doesn’t have to be clickable anyway.

    Example:

    class One_Line_Walker extends Walker
    {
        public function walk( $elements, $max_depth )
        {
            $list = array ();
    
            foreach ( $elements as $item )
            {
                if ( $item->current )
                    $list[] = "<b title='You are here'>$item->title</b>";
                else
                    $list[] = "<a href='$item->url'>$item->title</a>";
            }
    
            return join( "n", $list );
        }
    }
    

    In your theme use the walker like this:

    wp_nav_menu(
        array (
            'theme_location'  => 'your_theme_location',
            'walker'          => new One_Line_Walker,
            'container'       => '',
            'items_wrap' => '<p>%3$s</p>',
            'depth'           => 1
        )
    );
    

    See my post about items_wrap for an explanation of <p>%3$s</p>.

  2. Most time you only need to hook into the Walker::walk() method, for such cases, a Callback_Walker can do it which allows you to register a callback for it.

    If you make use of closures and a modern PHP version (>= 5.4) you can get some of the benefits of Closure::bind():

    class Callback_Walker extends Walker {
        private $callback = $callback;
    
        public static function create( $callback ) {
            return new self( $callback );
        }
    
        public function __construct( $callback, $bindClosure = TRUE ) {
            $this->callback = $callback;        
            if ( $bindClosure and $callback instanceof Closure ) {
                Closure::bind( $callback, $this, __CLASS__ )
            }
        }
    
        function walk( $elements, $max_depth ) {
            return $this->callback 
                   ? call_user_func( $this->callback, $elements, $max_depth )
                   : parent::walk( $elements, $max_depth );
        }
    }
    

    This alone does nothing so far, but blatantly copying the example by @toscho, this is how it could be used:

    wp_nav_menu(
        array (
            'theme_location' => 'your_theme_location',
            'walker'         => Callback_Walker::create( function( $elements, $max_depth ) 
            {
                $list = array();
    
                foreach ( $elements as $item )
                {
                    $list[] = $item->current
                        ? "<b title='You are here'>{$item->title}</b>"
                        : "<a href='{$item->url}'>{$item->title}</a>";
                }
    
                return join( "n", $list );
            } ),
            'container'      => '',
            'items_wrap'     => '<p>%3$s</p>',
            'depth'          => 1
        )
    );
    

    I hope he may excuse 😉

Comments are closed.