When number of posts on tag pages is less than 3.
I want to show more related or random posts, to fill max number of posts per page, which is 10.

How to achieve that? Is it possible to check number of posts in loop within default wordpress loop?

I use default wordpress loop which essentially looks like that.

<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
// posts
<?php endwhile; ?>
<?php endif; ?>

I tried changing this loop to wp_query but cannot make it work and would rather stick with default but then with default it might not be possible?

2 Answers 2


There are two steps to get this working:

  1. Add a counter to your main loop, so you can check how many posts are output.

  2. If your counter is less than 3, run a second query and output.

So for step 1, set a counter before your loop and increment it each time the loop runs, like so:

// create your counter variable
$counter = 0;
if (have_posts()) :
    while (have_posts()) : the_post();
    // add 1 to your counter, as 1 post was just output
    // (display the posts)
endif; ?>

Step two: check your counter variable, then run another query if needed.

// if counter is less than 3, run a separate query
if($counter < 3) {
    // get the ID of the current Tag
    $tag_id = get_queried_object()->term_id;
    // set up query arguments
    $args = array(
        // only pull Posts
        'post_type' => 'post',
        // don't pull Posts that have the current Tag - prevents duplicates
        'tag__not_in' => array("$tag_id"),
        // set how many Posts to grab
        'posts_per_page' => 3
    $extraPosts = new WP_Query($args);
        while($extraPosts->have_posts()) : $extraPosts->the_post();
        // display the posts)
} ?>

If you want the Tag Archive to always show exactly 3 posts, then right after the opening part of the "if" statement, calculate how many to get:

$numberToGet = 3 - $counter;

then set 'posts_per_page' => "$numberToGet" so it's dynamic.


Yes, you can, although I would not recommend using random pages, as anything involving randomness is very bad for performance, traffic scaling, and page load times

About $wp_query

The reason swapping have_posts for $wp_query->have_posts() won't do anything is twofold:

  • you have to actually check for the 3 posts
  • they are exactly the same thing

$wp_query is a global variable, and represents the main query, have_posts and the_post etc are all wrappers for global $wp_query; $wp_query->the_post() etc, where $wp_query is a WP_Query object

Now that we know it's a WP_Query object, we can google it and look at that classes docs and see that it has a member variable named:


The total number of posts found matching the current query parameters

So your check would be:

// after the main loop
global $wp_query;
if ( 4 > $wp_query->found_posts ) {
    // do something to make up the numbers here

That something could be to do another query for the latest posts, or pre-picked posts, an advertisement, who knows, perhaps even a WP_Query loop, but that's the subject of another question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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