Only display a certain number of posts, dependent on how many posts there are available in a query

I am trying to write some code for a slider of posts, at the moment my code involves two WP_Querys, one inside the other, but I can’t help feeling there may be a more efficient way of doing what I’m trying to achieve.

Steps are:

  1. Check how many published posts there are of a certain post type, using a WP_Query.
  2. If there are >= 4, I want to add a slider to the page, so I start printing out slider container.
  3. Then within the slider HTML, I use the count of posts from the first WP_Query ($num_posts) to work out how many posts I want to print out in the next query. If there are >= 12 available, I want to print all 12. If there are between 8 and 11 available, I want to print out only 8. If there are between 4 and 7 available, I want to print out only 4.
  4. I feed the number I want to print out ($postsToPrint) into showposts as an argument for the second WP_Query.

Is there any way of doing this without having two WP_Querys? It seems inefficient.

Explanation of code here:

    // Initial query which only exists so I can count available posts

    $args = array (
        'post_type'              => 'mytheme_posttype',
        'post_status'            => 'publish',
        'showposts' => 12
    );

    $sliderQuery = new WP_Query( $args );


    // Count how many available posts there are for my slider
    $num_posts = $sliderQuery->post_count;

    if ($num_posts >=4) : ?>

    // Want to add a slider if posts >= 4, so start printing out slider container HTML here.

    // I then want to check how many posts were collected in the above query, and only print out a certain number depending on how many there are available

        // if there are 12 available posts, print out all 12
        if ($num_posts >= 12) {
            $postsToPrint = 12;
        }

        //  else if there are between 8 and 11 available posts, only print out 8
        elseif ($num_posts >=8) {
            $postsToPrint = 8;
        }

        // if there are between 4 and 7 available posts, only print out 4
        else {
            $postsToPrint = 4;
        }

        // Second query for actually printing out posts.

        $args = array (
            'post_type'              => 'mytheme_posttype',
            'post_status'            => 'publish',
            'showposts' => $postsToPrint
        );

        $loop = new WP_Query( $args );

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

            // print out post thumbnail and some other post data in slider

        endwhile;

        // close slider container HTML

    endif;

Thanks!

Solutions Collecting From Web of "Only display a certain number of posts, dependent on how many posts there are available in a query"

You don’t have to run two queries, as you already got what you want (even more).

$args = array (
    'post_type' => 'mytheme_posttype',
    'post_status' => 'publish',
    'numberposts' => 12,
);
$sliderQuery = new WP_Query($args);

$num_posts = $sliderQuery->post_count;
if ($num_posts >=4) {

    if ($num_posts >= 12)
        $postsToPrint = 12;
    elseif ($num_posts >=8)
        $postsToPrint = 8;
    else
        $postsToPrint = 4;

    while ($sliderQuery->have_posts() && $postsToPrint--) {
        $sliderQuery->the_post();

        // Work with the post
    }
}

// EDIT
Okay, here’s a little explanation of what happens, and how/why this works…

Initially, $postsToPrint is set to what you want it to be (i.e., 4, 8, or 12 – depending on the total number of posts). We then decrement the counter variable ($postsToPrint-- is the same as $postsToPrint = $postsToPrint - 1). As long as we’ve not yet retrieved as many posts as we want, we go on. If we’ve reached our defined maximum posts number, we break (i.e., leave) the loop.

So, the above while() is an efficient version of the following, fully expanded version:

while ($sliderQuery->have_posts() && $postsToPrint > 0) {
    $sliderQuery->the_post();

    // Work with the post

    // We've handled another post, so decrement the number of posts to be handled
    $postsToPrint = $postsToPrint - 1;
}

I hope this makes it a little bit clearer…