4

I have two loops setup using WP_Query: $latest and $popular that I'm working to setup in this example layout:

Latest                                     Popular

enter image description here

Example HTML Output

<div class="content">

    <div class="posts latest">
        <post1>    
        <post2>
    </div>

    <div class="posts popular">
        <post10>    
        <post9>
        <post8>    
        <post7>
    </div>

    <div class="ad-block">
        <ad>
    </div>

</div>

<div class="content">

    <div class="posts latest">
        <post3>    
        <post4>
    </div>

    <div class="posts popular">
        <post6>    
        <post5>
        <post4>    
        <post3>
    </div>

    <div class="ad-block">
        <ad>
    </div>

</div>

[...]

Simply put: the Latests and Popular post divs are floated next to eachother and broken apart every few posts to accommodate an full width ad block.

My Loop

<div class="content">

    <div class="posts latest">

        <?php

        $args1 = array (
            'posts_per_page'    => 1000000,
            'order'             => 'DESC',
            'orderby'           => 'date'

        );

        $latest = new WP_Query( $args1 );

        if ( $latest -> have_posts() ) :

            $count = 0;

            while ( $latest -> have_posts() ) : $latest -> the_post();

                $count++;

                if ( $count % 5 == 0 ) :

                        get_template_part( 'template', 'post' ); ?>

                        </div> <!--/posts-latest-->

                        <div class="posts popular">

                            <?php

                            $args2 = array (
                                'posts_per_page'    => 10,
                                'order'             => 'ASC',
                                'orderby'           => 'date',
                            );

                            $popular = new WP_Query( $args2 );

                            if ( $popular -> have_posts() ) :

                                while ( $popular -> have_posts() ) : $popular -> the_post();

                                    get_template_part( 'template', 'post' );

                                endwhile;

                            endif;

                            ?>

                        </div> <!--/posts-popular-->

                        <div class="ad-block">
                            <?php get_template_part( 'template', 'ad' ); ?>
                        </div>

                    </div><!--/content-->    

                    <div class="content">

                        <div class="posts latest">

                <?php

                else :

                    get_template_part( 'template', 'post' );

                endif;

            endwhile;

        endif; wp_reset_postdata();

        ?>

    </div> <!--/posts-latest-->    

</div>

Right now this is setup so that every 5th posts in the $latest loop the $popular loop and a ad-block are added.

I understand why this doesn't work... Because every 5th post when the $popular loop is called it's starting again instead of continuing in order.

Any ideas on how I can make this work?

  • 1
    You should probably use $offset parameter in your WP_Query but at 1000000 posts per page I'm not sure how to add it in in a meaningful way... – Howdy_McGee Aug 22 '14 at 15:56
  • @Howdy_McGee Hey thanks for the tip. I'll read over that now. My goal with the large posts_per_page value is just to have all applicable posts be shown without any pagination - I knew it was a bit of a hack. – Rich Aug 22 '14 at 16:00
  • @Howdy_McGee $offset looks promising for sure. If I set posts_per_page on the popular loop to 10 and set and dynamicly set the value for $offset equal to how ever many posts have already been rendered I'm thinking that should work. Now just need to workout how I can accomplish that. – Rich Aug 22 '14 at 16:21
3

Try this: We declare an incrementer at the top of our outter loop called $popularLoop to keep track of how many popular loops we've been through, we assume we're going to at least hit 1.

Inside our Inner Loop (popular) we need to set how many posts per page we're going to load, multiple that by how many popular loops we've been through and that is going to give us our offset. At the end of our Inner Loop we increment $popularLoop so our offset stays consistent:

<div class="content">

    <div class="posts latest">

        <?php

        $args1 = array (
            'posts_per_page'    => 1000000,
            'order'             => 'DESC',
            'orderby'           => 'date'

        );

        $latest = new WP_Query( $args1 );
        $popularLoop = 0;

        if ( $latest -> have_posts() ) :

            $count = 0;

            while ( $latest -> have_posts() ) : $latest -> the_post();

                $count++;

                if ( $count % 5 == 0 ) :

                        get_template_part( 'template', 'post' ); ?>

                        </div> <!--/posts-latest-->

                        <div class="posts popular">

                            <?php
                            $popular_ppp = 10;
                            $popularOffset = $popular_ppp * $popularLoop;
                            $args2 = array (
                                'posts_per_page'    => $popular_ppp,
                                'offset'            => $popularOffset,
                                'order'             => 'ASC',
                                'orderby'           => 'date',
                            );

                            $popular = new WP_Query( $args2 );

                            if ( $popular -> have_posts() ) :

                                while ( $popular -> have_posts() ) : $popular -> the_post();

                                    get_template_part( 'template', 'post' );

                                endwhile;

                              $popularLoop++;
                            endif;

                            ?>

                        </div> <!--/posts-popular-->

                        <div class="ad-block">
                            <?php get_template_part( 'template', 'ad' ); ?>
                        </div>

                    </div><!--/content-->    

                    <div class="content">

                        <div class="posts latest">

                <?php

                else :

                    get_template_part( 'template', 'post' );

                endif;

            endwhile;

        endif; wp_reset_postdata();

        ?>

    </div> <!--/posts-latest-->    

</div>
  • Very nice. I started to do something somewhat similar using the existing $count variable but this approach looks a lot better. The only problem I'm having with it is that it starts counting at post 11. – Rich Aug 22 '14 at 16:42
  • 1
    whoops, $popularLoop should start at 0 instead of 1 (so that the offset is 0 when it hits the multiplication the first time). – Howdy_McGee Aug 22 '14 at 16:44
  • 1
    Works perfectly. I'd have spent all day trying to figure this one out without your help. Seriously.. Thanks man! – Rich Aug 22 '14 at 16:48

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.