The question:
I want 3 post with one loop iteration, so I’m using the_post()
to achieve this: (html removed)
<?php while ( have_posts() ) : the_post();
the_title();
the_post();
the_title();
the_post();
the_title();
endwhile; ?>
The problem starts, if number of posts is not divisible by 3. For example, if I have 5 posts, than this loop will still try to display 6 of them, generating empty html. How can I work it out? Or maybe I’m trying to achieve this functionality the wrong way?
@edit:
Here is HTML I wanna output to clarify my question:
<div class="row">
<div class="span3">
<h2>Title</h2>
<p>Content</p>
</div>
<div class="span3">
<h2>Title</h2>
<p>Content</p>
</div>
<div class="span3">
<h2>Title</h2>
<p>Content</p>
</div>
</div>
<div class="row">
<div class="span3">
<h2>Title</h2>
<p>Content</p>
</div>
<div class="span3">
<h2>Title</h2>
<p>Content</p>
</div>
<div class="span3">
<h2>Title</h2>
<p>Content</p>
</div>
</div>
So I want to surround every 3 posts with .row
.
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
Ultimately, this question is off-topic, because the solution has nothing to do with WordPress. Outputting posts in a grid pattern is an HTML/CSS issue, and the best-practice solutions don’t involve putting every three posts inside a separate containing <div>
. Even so, you can do what you want to do, using PHP (which, technically speaking, still makes this question off-topic).
I would start by querying a number of posts divisible by 3, or else setting posts_per_page
to a number divisible by 3. How you do that depends on whether you’re calling a new WP_Query()
for your custom-post type loop, or if you’re filtering pre_get_posts
to modify the default query. Either way, you would use the posts_per_page
query argument.
Then, you can simply define a counter inside the loop, and use it to close/open DIVs as necessary:
<div class="row">
<?php
$counter = 1;
if ( have_posts() ) : while ( have_posts() ) : the_post();
global $wp_query;
the_title();
the_content();
if ( ( 0 == $counter % 3 ) && ( $counter != $wp_query->posts_per_page ) ) {
?>
</div><div class="row">
<?php
}
$counter++;
endwhile; endif;
?>
</div>
The second part of the conditional ensures that you don’t get an empty div after the last row.
Method 2
After posting this question, I’ve had the “eureka” moment and achieved it (probably the ugly way) by surrounding my html for every post with simple if(get_the_title())
. So if title doesn’t exist, than don’t display anything. But I still think there is more pretty way of doing this.
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