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 a (relatively) tricky situation where my code requires changing the loop output every three posts, and within those three posts there are divs around two of the posts.

The code below displays 6 posts and I would want to loop though a total of 24 posts, repeating this four times.

Can anyone help? Thanks!

FIRST THREE

<div class="layer">

<div class="large left">
    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->
</div>

<div class="small left">
    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->

    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->
</div>

</div><!--layer-->

SECOND THREE

<div class="layer">

<div class="small left">
    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->

    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->
</div>

<div class="large right">
    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->
</div>

</div><!--layer-->
share|improve this question
add comment

4 Answers

up vote 1 down vote accepted

You can do this with much less code, using the modulo operator.

The modulo sign in PHP is %, and works like this: it gives you the remainder of a division, for example

5 % 2 = 1
9 % 3 = 0
11 % 7 = 4

So your code would look like this (I think you have a typo in your question, in the "First Three" the second block should be labeled small right. If I am wrong here, just edit the code below.)

For a better Overview, I start my Counter at 1, not as usual at 0, because it is easier to see which iteration is targeted by the conditionals. I also increase the counter at the last conditional - be sure you do not increment it twice!

So, before the Loop:

$counter = 1;

Then insinde the Loop:

<?php
    if ( $counter % 3 == 1 ) { // use this line for the first and the fourth iteration
        echo '<div class="layer">';
    }
        if ( $counter % 6 == 1 ) { // use this line for the first iteration only
            echo '<div class="large left">';
        } else if ( $counter % 6 == 2 ) { // use this line for the second iteration only
            echo '<div class="small right">';
        } else if ( $counter % 6 == 4 ) { // use this line for the fourth iteration only
            echo '<div class="small left">';
        } else if ( $counter % 6 == 5 ) { // use this line for the fifth iteration only
            echo '<div class="large right">';
        }
        //nothing to do for the sixth and the third iteration
        // the item is the same all the time
?>
        <div class="item">
            <?php the_title(); ?>
            <?php the_content(); ?>
        </div><!--item-->
<?php
        if ( $counter % 6 == 1 || $counter % 6 == 3 || $counter % 6 == 5 || $counter % 6 == 0 ) { // use this line everytime you close a subblock
            echo '</div>';
        }
    if ( $counter++ % 3 == 0 ) { // use this line for the third and the sixth iteration
        echo '</div>';
    }
?>
share|improve this answer
    
that is amazing! Perfect! Thanks a million. Plus you even caught my typo, I'm very impressed! –  Jacob Feb 7 '13 at 15:33
add comment

I think this would work:

<?php 
$counter = 1;
if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

<div class="layer">

    <?php if ($counter < 3) { ?>
        <div class="large left">
            <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
            </div><!--item-->
        </div>
        <div class="small left">
            <div class="item">
            <?php the_title(); ?>
            <?php the_content(); ?>
            </div><!--item-->

            <div class="item">
            <?php the_title(); ?>
            <?php the_content(); ?>
            </div><!--item-->
        </div>
    <?php
            $counter++;
        } elseif ($counter < 6) { ?>
            <div class="small left">
                <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
                </div><!--item-->

                <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
                </div><!--item-->
            </div>

            <div class="large right">
                <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
                </div><!--item-->
            </div>
    <?php
            $counter++;
        } else { 
            $counter = 0;
        }
    ?>
</div><!--layer-->
?>

Set a counter, if the loop is less than 3, do the first option, elseif the loop is less than 6 do the second option, else, reset the counter

share|improve this answer
    
Thanks for your quick response! What this code does is repeat the same post within the layer (so each div class="item" is fetching the same post) and it also uses the same one twice in a row (so "large left" first is presented twice, followed by two instances of "small left" first). I'll post code output below. –  Jacob Feb 7 '13 at 1:02
    
See source of output of Joshua's idea here: dev.collapsiblestudio.com/joshua.html –  Jacob Feb 7 '13 at 1:09
    
I set it up so that each layer was a post. I'll correct and give you a proper solution. Sorry about that. –  Joshua Richards Feb 7 '13 at 2:26
add comment

I think this may work, might need some refinement:

<?php if ($counter == 1){ ?>
    <div class="layer">
        <div class="large left">
            <div class="item">
            <?php the_title(); ?>
            <?php the_content(); ?>
            </div><!--item-->
        </div>
<?php } elseif ($counter == 2){ ?>}
        <div class="small left">
            <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
            </div><!--item-->

<?php } elseif ($counter == 3){ ?>}
            <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
            </div><!--item-->
        </div><!--end small left-->
    </div><!--end layer-->
<?php } elseif ($counter == 4){ ?>}
    <div class="layer">
        <div class="small left">
            <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
            </div><!--end item-->
<?php } elseif ($counter == 5){ ?>}
            <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
            </div><!--item-->
        </div><!--end small left-->
<?php } elseif ($counter == 6){ ?>}
        <div class="large right">
            <div class="item">
                <?php the_title(); ?>
                <?php the_content(); ?>
            </div><!--item-->
        </div>
    </div><!--layer-->
<?php }
    $counter++;
    if (($wp_query->current_post + 1) == ($wp_query->post_count)) {
        switch($counter){
            case 1:
                echo '</div><!--end layer-->';
                break;
            case 2:
                echo '</div><!--end small left-->
                        </div><!--end layer-->';
                break;
            case 3:
                break;
            case 4:
                echo '</div><!--end small left-->
    </div><!--end layer-->';
                break;
            case 5:
                echo '</div><!--end layer-->';
                break;
            case 6:
                break;
            default:
                break;
        }
    }
endwhile;?>
share|improve this answer
add comment

For reference, someone on another forum achieved the same correct output slightly differently (although using the same principles...). Thanks to both!

<?php 
while( have_posts() ) : the_post();

$position = $wp_query->current_post;
$p3 = $position%3;
$p6 = $position%6;
$number_posts = $wp_query->post_count-1;

if( $p3 == 0 ) echo '<div class="layer">';
if( $p6 == 0 ) echo '<div class="large left">';
elseif( $p6 == 1 || $p6 == 3) echo '<div class="small left">';
elseif( $p6 == 5 ) echo '<div class="large right">'; ?>

    <div class="item">
    <?php the_title(); ?>
    <?php the_content(); ?>
    </div><!--item-->

<?php if( $position == $number_posts || in_array($p6, array(0, 2, 4, 5)) ) echo '</div>';
if( $p3 == 2 || $position == $number_posts ) echo '</div><!--layer-->'; 

endwhile; ?>
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.