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 have written a custom walker that I am using with wp_nav_menu but I need to iterate through 4 custom classes, and I'm not sure how to do this. Basically, each menu-item <li> needs to be given a class of color1, color2, color3 or color4, cycling back to color1, lather, rinse, repeat, in that order.

Ordinarily I would do this with a $i and a $i++, but how do I do this in the Walker class?

EDIT: My Walker class code:

class Salamander_Advent_Walker extends Walker_page {
function start_el(&$output, $item, $depth, $args) {
    if ( $depth ) {
        $indent = str_repeat("\t", $depth);
    } else {
        $indent = '';
    }

    $advent_thumbnail = get_post_meta($item->ID, 'advent-thumb', true);
    $advent_slug = get_post_meta($item->ID, 'advent-slug', true);
    $advent_oneliner = get_post_meta($item->ID, 'advent-oneliner', true);
    //$description = get_post_meta($item->ID, 'advent-thumb', true);

    $output .= $indent . '
    <li class="active color4">
        <a href="#day'. $advent_slug .'">
            <span class="day">
                <strong>'. $advent_slug .'</strong>
                <span>&nbsp;</span>
            </span>
            <span class="content">
                <small>'. $advent_slug .'</small>
                <img src='. $advent_thumbnail .' width="126" height="91" alt="advent" />
                <strong>'. $advent_oneliner .'</strong>
            </span>
        </a>';                      
}

}

share|improve this question

3 Answers 3

up vote 1 down vote accepted

Use a class variable to keep the 'index' of the colour you wish to display. Increment each time it's used, and check if it goes over, in which case set it back to 1.

class Salamander_Advent_Walker extends Walker_page {
    private $color_idx = 1;
    function start_el(&$output, $item, $depth, $args) {
        if ( $depth ) {
            $indent = str_repeat("\t", $depth);
        } else {
            $indent = '';
        }

        $advent_thumbnail = get_post_meta($item->ID, 'advent-thumb', true);
        $advent_slug = get_post_meta($item->ID, 'advent-slug', true);
        $advent_oneliner = get_post_meta($item->ID, 'advent-oneliner', true);
        //$description = get_post_meta($item->ID, 'advent-thumb', true);

        $output .= $indent . '
        <li class="active color'.$this->color_idx.'">
            <a href="#day'. $advent_slug .'">
                <span class="day">
                    <strong>'. $advent_slug .'</strong>
                    <span>&nbsp;</span>
                </span>
                <span class="content">
                    <small>'. $advent_slug .'</small>
                    <img src='. $advent_thumbnail .' width="126" height="91" alt="advent" />
                    <strong>'. $advent_oneliner .'</strong>
                </span>
            </a>';              
        $this->color_idx++;
        if ($this->color_idx > 4) {
            $this->color_idx = 1
        }
    }

}
share|improve this answer

Create a separate function:

function alternate()
{
    static $i = 0;
    $args = func_get_args();

    return $args[ $i++ % func_num_args() ];
}

In your walker use it like this:

$class = 'color' . alternate( 1, 2, 3, 4 );
// somewhere in your output string:
$output .= '<li class="active ' . $class . '">';
share|improve this answer
2  
The static counter could also be a class var, same thing just less a function. –  Mark Duncan Feb 3 '12 at 17:19
1  
@MarkDuncan I am a fan of atomic functions: one function per task. It makes debugging so much easier. :) –  toscho Feb 3 '12 at 17:29
    
Sounds logical, not sure i'd personally use a function for counting alone, but a valid approach nonetheless. –  Mark Duncan Feb 3 '12 at 20:12
    
Sorry appendum, there's a problem with your sample code(the second sample is invalid, as is)... –  Mark Duncan Feb 3 '12 at 20:16
    
@MarkDuncan How exactly? –  toscho Feb 3 '12 at 20:27

You can do that by setting the incrementing number to a global variable.

function start_el(&$output, $item, $depth, $args) {
    //globalize the variable
    global $ac_color_num;
    //check if it is set, or if it is 4 (to reset to 1)
    if ( !isset($ac_color_num) || $ac_color_num == 4 ) { $ac_color_num = 1; }
    $ac_color_num++
    if ( $depth ) {
        $indent = str_repeat("\t", $depth);
    } else {
        $indent = '';
    }

    $advent_thumbnail = get_post_meta($item->ID, 'advent-thumb', true);
    $advent_slug = get_post_meta($item->ID, 'advent-slug', true);
    $advent_oneliner = get_post_meta($item->ID, 'advent-oneliner', true);
    //$description = get_post_meta($item->ID, 'advent-thumb', true);

    //use $ac_color_num in the output.
    $output .= $indent . '
    <li class="active color' . $ac_color_num . '">
        <a href="#day'. $advent_slug .'">
            <span class="day">
                <strong>'. $advent_slug .'</strong>
                <span>&nbsp;</span>
            </span>
            <span class="content">
                <small>'. $advent_slug .'</small>
                <img src='. $advent_thumbnail .' width="126" height="91" alt="advent" />
                <strong>'. $advent_oneliner .'</strong>
            </span>
        </a>';                      
}
share|improve this answer
1  
There're already too many globals and conflicts are just about to happen. If you add a global, then only if you really have to and even then, you should prefix it. –  kaiser Feb 3 '12 at 16:02
    
Fair enough. The other answer is more elegant, but mine still solves the problem - not sure if it warrants a downvote... I will say that the likelihood of $color_num conflicting is really low, especially in the scope of any process that this walker would be run in. –  Drew Gourley Feb 3 '12 at 17:05
1  
By scope I meant the entire process. Added prefix ac_ for 'amanda custom'. Thanks. –  Drew Gourley Feb 3 '12 at 19:33
2  
Just a sidenote: Instead of calling get_post_meta() several times, you can also do extract( get_post_custom( $post->ID ), EXTR_SKIP ); which gives you the same vars you used with a simple one-liner. Oh, and you're missing a space between the classes: "active color' . $ac_color_num . '". –  kaiser Feb 3 '12 at 19:44
1  
That's a nice move with get_post_custom - I was just doing a copypasta of her code and adding my stuff in. the lack of a space is so the class is color3 instead of color 3 - I'm just outputting the number. –  Drew Gourley Feb 3 '12 at 22:08

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.