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-->
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 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>';
}
?>
Method 2
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
Method 3
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;?>
Method 4
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; ?>
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0