1

Here's the layout, I'd like to achieve.

  • 1st row: three posts in three columns from category A
  • 2nd row: one fullwidth post from category B
  • 3rd row: the next three posts from category A
  • 4th row: the next post from category B
  • etc.

It looks like this:

-------------------------
| CAT A | CAT A | CAT A |
-------------------------
|         CAT B         |
-------------------------
| CAT A | CAT A | CAT A |
-------------------------
|         CAT B         |
-------------------------
| CAT A | CAT A | CAT A |
-------------------------
|         CAT B         |

Basically there are two loops, one inside each other, running in parallel and individually.

I can get the number of current post of the main loop by $wp_query->current_post and insert a new WP_Query after each third post with only one post (by posts_per_page=>1) and offset by the number of previous posts (by offset=>$wp_query->current_post).

I'm afraid this is a very memory intensive thing to call a new WP_query after each third post. Are there any better alternatives to display posts in the markup I specified above? Many thanks.

1

Here's what you can do. At the top of your page, run your first WP_Query. Calculate the number of posts you need for your secondary query by using the number of posts IN query cat_a divided by 3 and using PHP floor() to drop any remainder. This will ensure that your second query only has the exact number of posts needed to get the pattern your desire.

When displaying we can use PHP Modulus to display our cat_b post before cat_a 4 ( increments ) ever displays. In this case I enter The Loop of cat_b but break out so WordPress keeps track of where we are in our loop and we don't need to.

Altogether, the idea looks something like this. I haven't tested any of it so if you run into issues turn on debugging and see if you can fix any PHP errors.

$cat_b = '';
$cat_a = new WP_Query( array(
    'category'          => 'a',
    'posts_per_page'    => 60,
) );

if( $cat_a->have_posts() ) {
    $num_posts = floor( $cat_a->post_count / 3 );

    if( $num_posts > 0 ) {
        $cat_b = new WP_Query( array(
            'category'      => 'b',
            'posts_per_page'=> $num_posts,
        ) );
    }
}


if( $cat_a->have_posts() ) : $index = 1; ?>

    <?php while( $cat_a->have_posts() ) : $cat_a->the_post(); ?>

        <?php if( ! empty( $cat_b ) && 0 == $index % 4 && $cat_b->have_posts() ) : ?>

            <?php while( $cat_b->have_posts() ) : $cat_b->the_post();

                <h1><?php the_title(); ?></h1>

            <?php
                wp_reset_postdata();
                break;
                endwhile;
            ?>

        <?php endif; ?>

        <h1><?php the_title(); ?></h1>

    <?php
        $index++;
        endwhile;
    ?>

<?php
    wp_reset_postdata();
    endif;
?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.