Does WordPress Loop have a function like Shopify’s cycle?

Shopify’s Cycle lets you alternate between things within a loop. Here’s my example:

    <div class="{% cycle 'first', 'second', 'third' %}">
      {% include 'product-grid-item' %}
    </div>

My question, is there anything like this for WordPress? I’d love to be able to cycle through some kind of setting – such as class names – as each item in my loop is printed.

Related posts

Leave a Reply

4 comments

  1. Short answer, no.

    But that is a pretty cool feature!

    To so something similar in WordPress, you’d need to code some kind of iterator in PHP and have it do the logic for you. For example:

    $classes = array( 'first', 'second', 'third' );
    $iteration = 0;
    if ( have_posts() ) : while ( have_posts() ) : the_post();
        $iteration = $iteration >= count($classes) ? 0 : $iteration;
        $class = $classes[$iteration];
        ?>
    
        <div class="<?php echo $class; ?>">
            <!-- Whatever other stuff you need to do -->
        </div>
    
        <?php
        $iteration++;
    endwhile; endif;
    
  2. There’s nothing built into core but it’s easy to make something like this yourself. Here’s an example that would give posts classes post-count-1, post-count-2, post-count-3, post-count-1, ….2, ….3, …1, etc.:

    <?php
    \ start the counter at 1
    $counter = 1;
    \ start the loop
    while->have_posts() : the_post();
    \ figure out our count
    $count = 'post-count-' . $counter % 3;
    ?>
    <article <?php post_class( $count ); ?>>
        \ some more stuff like the title and content
    </article>
    <?php
    \ advance the counter
    $counter++;
    \ keep looping until the end
    endwhile;
    ?>
    

    If you wanted plain English classes, you’d need an if or switch statement to set $count. This example also uses post_class which gives you some other useful classes.

    ADDENDUM:
    I should add that if you don’t need extensive browser support (:nth-child() CSS selector is really the right solution if you need the classes purely for styling. jQuery also supports this selector and you can use it to add the classes after page-load if you need better-than-the-CSS browser support.

  3. Not exactly, but WordPress does have body_class and post_class , which by default will give you custom selectors, which can further be customized with any name or variable of your choosing.

    http://codex.wordpress.org/Function_Reference/body_class
    http://codex.wordpress.org/Function_Reference/post_class

    You are also able to use them as a filter, for example;

    add_filter('body_class','my_class_names');
    
    function my_class_names($classes) {
        // Some conditional
        $classes[] = 'my-custom-class-name';
        // return the $classes array
        return $classes;
    }
    

    ps. Sorry I misunderstood the question, didn’t realize you wanted it exactly the same in terms of numerical classing.

  4. This is one of my favorite helpers in Rails (which Shopify created a link to in its Liquid template language). I wrote a function similar to this for WordPress, enjoy:

    /**
     * Cycle/alternate unlimited values of a given array.
     * For instance, if you call this function five times with wp_cycle('three', 'two', 'one'),
     * you will in return get: three two one three two. This is useful for loops and allows you to
     * cycle classes.
     * For instance, foreach ($posts as $post) { echo '<div class="'.wp_cycle('odd','even').'">...</div>'; }
     * would alternate between <div class="odd">...</div> and <div class="even">...</div>. Neat, huh?
     * You can pass any data as args and as many as you want, e.g. wp_cycle(array('foo', 'bar'), false, 5, 'silly')
     *
     * @param mixed Accepts unlimited args
     * @return mixed
     * @author Matthew Boynes
     */
    function wp_cycle() {
        global $wp_cycle_curr_index;
        $args = func_get_args();
        $fingerprint = substr( sha1( serialize( $args ) ), 0, 7 );
        if ( !is_array( $wp_cycle_curr_index) ) $wp_cycle_curr_index = array();
        if ( !isset( $wp_cycle_curr_index[ $fingerprint ] ) || !is_int( $wp_cycle_curr_index[ $fingerprint ] ) ) $wp_cycle_curr_index[ $fingerprint ] = -1;
        $wp_cycle_curr_index[ $fingerprint ] = ++$wp_cycle_curr_index[ $fingerprint ] % count( $args );
        return $args[ $wp_cycle_curr_index[ $fingerprint ] ];
    }