0

How can I intervene in my post loop output to show 3 posts in alternate mark-up, and then resume?

I have a post loop that calls my post card template fragment, card-pair_top.php, to display like this...

enter image description here

But, when the post count is high, it looks repetitive. So, at key points, I want to change the layout for visual variance. I want to use my 'feature' card-overlay.php theme fragment...

enter image description here

I want to do this using the same single WP_Query results, $posts_topic_remainder, rather than make multiple queries, partly as I want to retain tidy pagination.

Specifically, at points 19, 31 or 43 in the while have_posts loop, I'd like to break the column divs, and even the row div, and insert a new nested row mark-up set which itself should display the next three posts using card-overlay.php.

Then it should restore the mark-up and resume displaying the loop contents using card-pair_top.php, until the next break.

Here is the original loop output...

    <!-- Posts row -->
    <div class="row px-2">
        <?php
            $i=0;
            // Post Loop
            while ( $posts_topic_remainder->have_posts() ) {
                $posts_topic_remainder->the_post();

                // Impose an offset, skip same number used in features above
                $i++;
                if($i<=$num_features) continue;

                // set_query_var( 'tax_slug_to_do', $this_terms_tax_slug );
                set_query_var('columns',  $post_classes);
                // Get Loop template
                get_template_part('partials/loops/card', 'pair_top');

            }
            wp_reset_postdata();
        ?>
    </div><!-- end .row -->

And here is some code where I use a basic conditional to break the divs and introduce a new row...

    <!-- Posts row -->
    <div class="row px-2">
        <?php
            $i=0;
            // Post Loop
            while ( $posts_topic_remainder->have_posts() ) {
                $posts_topic_remainder->the_post();

                // Impose an offset, skip same number used in features above
                $i++;
                if($i<=$num_features) continue;




                if ($i == 19 OR $i == 31 OR $i == 43) { ?>
                </div><!-- break .row of .pair_tops -->

                    <div class="row showcase pt-4 pb-4">
                        <!-- CONTENT COLUMN -->
                        <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
                            <!-- Posts row -->
                            <div class="row posts-row">


                                <?php
                                /* *********************************** */
                                /*           Features                  */
                                /* *********************************** */
                                 echo '<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4 col-xl-4">';

                                        set_query_var('queried_object',$queried_object);

                                        set_query_var('use_byline', 'true');

                                        if ( $queried_object->slug == 'essays') {
                                             set_query_var('use_source', 'true');
                                        } else {
                                             set_query_var('use_source', 'false');
                                        }

                                        if ($queried_object->name == 'session') {
                                             $card_type = 'overlay_session';
                                        } else {
                                             $card_type = 'overlay';
                                        }
                                        get_template_part('partials/loops/card', $card_type);

                                 echo '</div>';
                                ?>


                            </div>
                        </div>
                    </div>

                    <div class="row px-2"><!-- resume .row of .pair_tops -->
                <?php
                }


                // Tell loop template which taxonomy to loop through (set above ^)
                set_query_var('columns',  $post_classes);
                // Want to hide last N items for responsive-space reasons? Pass these vars

                // Get Loop template
                get_template_part('partials/loops/card', 'pair_top');

            }
            wp_reset_postdata();
        ?>
    </div><!-- end .row -->

That gets me to this, which is half-way...

enter image description here

The issues with my code are...

  • Whilst I have successfully introduced an alternate row and displayed a single post, I need to display three. How do I do that? (It is the "Features" div inside .row .posts-row which must be rendered for three posts).
  • How do I then stop the three posts in question from being rendered through card-pair_top.php subsequently, when the standard-layout loop resumes?

I'm open to changes of approach.

1

There are a number of ways you can break this up. I think you have the right idea though to break it inside of your current loop with $i, but maybe something simple that is readable could be changing this:

if ($i == 19 OR $i == 31 OR $i == 43) { ?>

Into this:

if(
    in_array($i, range(19, 21)) ||
    in_array($i, range(31, 33)) || 
    in_array($i, range(43, 45))
) { ?>

You could take it a deeper and create an array that could control the number you want to start with and an offset of that number to be flagged as a Featured post.

Hope this helps!!

  • thanks. Not sure I quite understand how to get 3 posts going. If I understand correctly, your conditional would replace my conditional. But my conditional sets up one intervening row (correct) and only one post as feature (not enough). At post 19, I would want to instigate the breaking row, then render posts 19, 20 and 21 as feature, then reinstate the normal output at 22. Not sure how to accommodate that. – Robert Andrews Jun 24 at 17:19
  • Yes, the conditional I wrote will allow your post as a featured post. The conditional I wrote says, If post is 19, 20, 21, 31, 32, 33, 43, 44, or 45....then render as featured. (I hope I am understanding you correctly) – ChristopherJones Jun 24 at 17:31
  • Not quite, I think. You see, whilst the "features" div bearing $overlay_classes is the post for repetition 3 x times, the nested three divs outside it (.row .showcase..., <!-- CONTENT COLUMN --> and <!-- Posts row -->) construct a single row designed to hold those three things. I can't just render the card-overlay feature card the loop flow - those depend on being wrapped by this single row mark-up. So the code needs to insert this single row at the appropriate place (as it does), then render 3 x posts as features ( so far, I have only 1), then flip back to normal. – Robert Andrews Jun 24 at 20:35
  • You could drop my logic after the <div class="row posts-row"> and close that if() statement BEFORE you close that <div class="row posts-row"> row?? And leave your if() statement alone. It is not the cleanest thing in the world, but it will function as I think you need. – ChristopherJones Jun 25 at 14:27
  • 1
    Ultimately, I decided that inserting an intermediary row to break the flow and inserting three posts of alternate layout was the wrong/lazy way for me to go. So, instead, I altered some CSS rules to ensure that the "feature" card is less dependent on being in that intermediary row, so that it would display properly even if normally rendered in the same flow as the regular cards. You had assumed, as you should have done, that I was using this method, but I had been over-complicating it. Thanks for also suggesting the range idea. My code now looks like pastebin.com/ApZSe9Zi Thanks. – Robert Andrews Jun 27 at 14:49

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.