I've set up a custom walker, and it works as desired when I hard code my variable.

What I want is to be able to call my walker and pass it a variable that is used in the walker.

For example:

 'walker'          => new Plus_walker($refine => 'review'), 

The walker I've tweaked to output http://URL/review in order to find posts in the review category for this menu item. But I want to be able to use the same walker for 'previews', 'interviews' and more. Thus far my attempts at inputting variables have just broken the whole thing, 'Parse error: syntax error, unexpected T_DOUBLE_ARROW'.

I know I could just rewrite the code and make a few different walkers (Review_walker, Preview_walker etc), but this just seems wrong (and I figure this could be an important thing to know...)

My walker code is here:

class plus_walker extends Walker_Nav_Menu {

    var $refine;

        function __construct($refine) {

            $this->refine = $refine;

      function start_el(&$output, $item, $depth, $args)
           global $wp_query;
           $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

           $class_names = $value = '';

           $classes = empty( $item->classes ) ? array() : (array) $item->classes;

           $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
           $class_names = ' class="'. esc_attr( $class_names ) . '"';

           $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

           $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     )  . '' : ''; //This is where I want the argument to live.

    $modded_url = substr($attributes,0,-1) . '+' . $refine . '"';

            $item_output = $args->before;
            $item_output .= '<a'. $modded_url .'>';
            $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
            $item_output .= $description.$args->link_after;
            $item_output .= '</a>';
            $item_output .= $args->after;

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

And the php call in my templates:

<?php wp_nav_menu( array(
                            'menu' => 'Handheld', 
                                'container'       => 'div', 
                                'container_class' => 'col_1', 
                                //'container_id'    => ,
                                'menu_class'      => 'menu', 
                                //  'menu_id'         => ,
                                'echo'            => true,
                                'fallback_cb'     => 'wp_page_menu',

                                'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
                                'depth'           => 0,
                                'walker'          => new Plus_walker(array($refine => 'review')), 


        ); ?>

I've tried a bunch of different configurations: 'refine' => 'review, with and without the array, but still no joy, just errors (unexpected '=>' mostly).

3 Answers 3


Native walker are triggered with walk() method and are not set up to receive data on creation. You can define custom property and constructor method for this purpose:

class plus_walker extends Walker_Nav_Menu {

    var $refine;

    function __construct($refine) {

        $this->refine = $refine;



'walker' => new plus_walker('review');

After this you can access your custom data as $this->refine in walker's methods.

  • Hey Rarst.I've tried implementing that, but I keep getting errors. I've updated my code, and included the template call to the walker function. Am I missing something?
    – josh
    Oct 19, 2011 at 14:27
  • @josh you can't just use $refine, you need to use $this->refine inside methods. Also you are trying to pass array, note that my example is for single simple variable.
    – Rarst
    Oct 19, 2011 at 14:41

One other way involves adding a custom argument to the wp_nav_menu() function. This is handy if you need to pass a value from outside of the walker class altogether:

wp_nav_menu( array( 
    'theme_location' => 'secondary',
    'depth' => 1,
    'walker' => new Custom_Walker(),
    'walker_arg' => 'Custom argument value here'
) );

From within the walker class you can then access this custom arg from within start_el() function inside of the walker class (Walker_Nav_Menu::start_el()) like this:

$custom_arg = esc_attr( $args->walker_arg );

Hopefully this helps, it helps with a few obscure scenario's I've come across that Rarst's recommendation above may can't handle well.

  • Thanks, this is exactly what I needed! I had to change $args->walker_arg to $args['walker_arg'] to get the values to pull through, in case anyone else has the same problem!
    – louiser89
    Mar 2, 2015 at 14:23

You can simply get the custom argument with a slightly altered start_el() function.

First of all, call the element wp_nav_menu (or any other walker using function) with the arguments specified in Kevin Leary's answer.

In the start_el function in your custom walker you can access your data simply via $args['walker_arg']; notice that walker_arg can be altered to fit your needs.

Additionally, with this and partly with Kevin Leary's solution, you can pass more than one custom argument to the walker!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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