0

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

4 Answers 4

1

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>';
    }
?>
1
  • that is amazing! Perfect! Thanks a million. Plus you even caught my typo, I'm very impressed!
    – Jacob
    Feb 7, 2013 at 15:33
0

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

3
  • 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, 2013 at 1:02
  • See source of output of Joshua's idea here: dev.collapsiblestudio.com/joshua.html
    – Jacob
    Feb 7, 2013 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. Feb 7, 2013 at 2:26
0

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;?>
0

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

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.