Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WP_Query sometimes returns zero results when there are matching posts - why?

Tags:

wordpress

This one has got me stumped.

I have a category.php file which contains this loop:

<?php
if ( have_posts() ) : ?>
    <?php
    while ( have_posts() ) : the_post(); ?>
        <div class="entry-content description clearfix">
            <h2 class="category-subtitle"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
            <?php echo the_content(); ?>
            <?php global $withcomments; $withcomments = 1;
    ?>
        </div><!-- .entry-content -->
    <?php
    endwhile;
else :
    get_template_part( 'content', 'none' );
endif;
?>

This block of code works fine and always returns the results one would expect.

In addition, outside the loop (after it, in case that matters), I've got a column to one side with this loop - I'm going to refer to this as the newsfeed loop for the sake of clarity:

<h3 class="newsfeed-heading"><a href="/category/news/">Latest News</a></h3>
<?php
    // wp_reset_query(); * Same results with or without wp_reset_query
    $args = array(
    'cat' => 89,
    'order'   => 'ASC'
    );
    $custom_query = new WP_Query($args);
    //echo "<h2>Found: $custom_query->found_posts</h2>";
    while($custom_query->have_posts()) : $custom_query->the_post();
?>
    <div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
        <h4 class="highlight1"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4>
        <p><?php $content = get_the_content(); echo mb_strimwidth($content, 0, 160, '...');?></p><div class="morelink"><a title="<?php the_title(); ?>" href="<?php the_permalink(); ?>">Read more</a></div>
    </div>
<?php endwhile; 
  // wp_reset_postdata();  * Same results with or without wp_reset_postdata
?>

Now, in the majority of cases, these two loops play nicely together and both loops return the set of results I'd expect. But not always.

As far as I can tell, I think if the main category loop only contains one result, then the newsfeed loop is always correct. But if the main category loop has multiple posts in the results set, the newsfeed loop frequently works fine. So I have not been able to spot a pattern.

I have tried putting wp_reset_query(); in different places, clutching at straws, but it doesn't make any difference.

Incidentally, when the newsfeed loop works, it always returns the correct results set. But when it doesn't, it always returns nothing and $custom_query->found_posts returns zero.

I would really appreciate some advice on where to look for a possible solution.

like image 434
Jon Ewing Avatar asked Jul 21 '15 19:07

Jon Ewing


People also ask

What is the difference between WP_Query and Get_posts?

The difference between wp_query() and get_posts() is basically the type of loop you want to use to display the posts on the front end. So in the end it mainly boils down to your preference and comfort.

What is Suppress_filters WP_Query?

'suppress_filters' =>true This is the important one, what this does is, it stops filters from altering the query. So pre_get_posts and the build in posts_* filters cannot be used to alter get_posts . This is why in your case you get posts using get_posts and none using WP_Query.

Where is WP_Query defined?

What is WP_Query? As we mentioned, WP_Query is a PHP class used by the WordPress database. This particular class can do several things, but primarily it's used to pull posts from the database. As its name indicates, it makes a query based on the criteria you set for it.

What is global $WP_Query?

This global is only set by the site owner (e.g., in wp-config. php), and contains an array of IDs of users who should have super admin privileges. If set it will override the list of super admins in the database. $wp_query (object) The global instance of the Class_Reference/WP_Query class.


2 Answers

For anyone searching, found_posts returns 0 if arguments is using 'no_found_rows' => true.

like image 198
Jonas Lundman Avatar answered Oct 24 '22 07:10

Jonas Lundman


You are missing wp_reset_postdata(); after your custom query. As soon as you call the_post(), you are setting the $post global to the value of the current post. This is true for the main query and any custom instance of WP_Query. In get_posts, this happens when you call setup_postdata().

As already pointed out, wp_reset_query() is used with query_posts which you should never use as it breaks the main query object and anything that relies on the main query object like related posts, pagination and page functionality.

If the above does not work, look for any posts_** filters or any instance of pre_get_posts that is poorly written in your theme or a plugin. Apart from these suggestions, your code should work.

like image 40
Pieter Goosen Avatar answered Oct 24 '22 06:10

Pieter Goosen