I've created a custom post type and cannot seem to get my if-statements to work for displaying different layouts properly depending on the amount of items in my while-loop. What I want to achieve is to check how many CPT is set and depending on the amount of posts display different layout.
For exemple: if one CPT is set, display 100% width, if two CPT display 50% width each column and so on and so forth.
I have already predefined some css layout classes which i use in my html-containers.
To my problem, is that I don't understand why my if-statements doesn't work for displaying my column-layouts. My first if-statement, which is checking for when a single post is set and the amount is equal to 1 works as it should and displays the layout-design I want.
What I don't understand is when I check for the amount of post equal to 2 in my else if-statement, my first and second post gets separately layout classes, which leads to them getting stacked on top of each other, instead of display side by side. I really need some help with this logic for better understanding looping out content in wordpress.
Thanks!
$puff_arg = array(
'post_type' => 'Puff',
'posts_per_page' => 10,
);
$puff = new WP_Query ( $puff_arg );
if ( $puff->have_posts() ) {
while ( $puff->have_posts() ) {
$puff->the_post();
$heading = get_post_meta($post->ID, 'heading');
$text = get_post_meta($post->ID, 'text');
// counts posts in loop and increment by 1
$count_posts = $puff->current_post + 1;
// Check amount of post to 1
if ( $count_posts === 1 ) {
<!-- Display layout with 1 Image -->
<div class="col-12">
<div class="">
<h3><?php echo $heading[0] ? $heading[0]: ''; ?></h3>
<p><?php echo $text[0] ? $text[0]: ''; ?></p>
</div>
</div>
// Check amount of post to 2
} else if ( $count_posts === 2 ) {
<!-- Display layout with 2 Images -->
<div class="col-6">
<div class="">
<h3><?php echo $heading[0] ? $heading[0]: ''; ?></h3>
<p><?php echo $text[0] ? $text[0]: ''; ?></p>
</div>
</div>
// Check amount of post to 3
} else if ( $count_posts === 3 ) {
<!-- Display layout with 3 Images -->
<div class="col-4">
<div class="">
<h3><?php echo $heading[0] ? $heading[0]: ''; ?></h3>
<p><?php echo $text[0] ? $text[0]: ''; ?></p>
</div>
</div>
}
}
wp_reset_postdata();
}
As you suspected there is a problem with your loop's logic. When the first post in the Puff post type is accessed in the loop the value of $puff->current_post will be equal to 0 (the first item in the array). This means that the if ( $count_posts === 1 ) {
condition will be true and the first post's HTML will have the col-12
class. The next post in the loop is the second post so $puff->current_post
will be equal to 1. Therefore the second statement } else if ( $count_posts === 2 ) {
will be true and the second post will have the col-6
class. This is the reason why your posts don't align - the first one has has the col-12
class (which takes 100% of the screen) while the second one has the col-6
class (half the screen).
The solution to you problem is simple. Use WP_Query's found_posts
method to determine the amount of retrieved posts before looping through them. This way you don't have to check each post's number. Additionaly, since it seems the only difference between the layouts is the col class I believe you can simplify your code even further. Here's how it will look:
$puff_arg = array(
'post_type' => 'Puff',
'posts_per_page' => 10,
);
$puff = new WP_Query ( $puff_arg );
if ( $puff->have_posts() )
{
switch ($puff->found_posts)
{
case '2':
$colClass = 'col-6';
break;
case '3':
$colClass = 'col-4';
break;
default:
$colClass = 'col-12';
}
while ( $puff->have_posts() ) {
$puff->the_post();
$heading = get_post_meta($post->ID, 'heading');
$text = get_post_meta($post->ID, 'text');
?>
<div class="<?php echo $colClass; ?>">
<div>
<h3><?php echo $heading[0] ? $heading[0]: ''; ?></h3>
<p><?php echo $text[0] ? $text[0]: ''; ?></p>
</div>
</div>
<?php
}
}
wp_reset_postdata();
You can get the count of WP_Query
by $wp_query->post_count
or by $wp_query->found_posts
. With post_count
you can get amount of posts on each page (for example if you set it with posts_per_page
in your query, with found_posts
you can get the total number of posts that exist in the database.
So in your example you can move like this:
$count = $puff->post_count;
if ($count == 1) {echo '<div class="col-12">';}
if ($count == 2) {echo '<div class="col-6">';}
if ($count == 3) {echo '<div class="col-4">';}
//main loop actions
echo '</div>';
If you control the number of queried CPT's to fit in a 12 column grid (that's 1, 2, 3, 4, 6 or 12), you could simplify this conditional approaches as:
<div class="col-<?= 12 / $puff->post_count ?>">
<!-- Your post title and details here -->
</div>