Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

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.

share|improve this question
    
Depends on what you mean with minimal. This is probably hard to beat. –  toscho Sep 1 '13 at 9:07
    
@toscho That is very useful. I just need to add the .current-menu-item class because the active page must be highlighted. –  danijar Sep 1 '13 at 9:14
add comment

2 Answers

up vote 3 down vote accepted

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>.

share|improve this answer
add comment

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 ;)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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