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.

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

share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

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

}

//stuff

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

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

share|improve this answer
    
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 '11 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 '11 at 14:41
add comment

In case someone is still looking for an answer (as I was)

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 as by kevinlearynet.

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 kevinlearynet's solution) you can pass more than one custom argument to the walker!

share|improve this answer
add comment

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.

share|improve this answer
    
Excellent method. Thanks, @kevinlearynet ! –  cale_b Feb 4 '13 at 17:15
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.