Recommended way to drop a pending query (in pre_get_posts)?

There’s not really a way to “stop” the main query. There are plenty of filters to modify it, just nothing to turn it off completely. The best you may be able to do is hook into posts_request, which fires right before the data is hit, and return an empty string or something non-sensical. This is still going to hit the database.

Example (untested):

<?php
add_filter('posts_request', 'wpse83187_posts_request', 10, 2);
function wpse83187_posts_request($sql, $query)
{
    if (!$query->is_main_query() /* other conditionals here! */) {
        return;
    }

    return '';
}

Instead of creating your own WP_Query looks in the template, why not just completely reset the query with pre_get_posts?

Then use the “main” loop for at least one of your WP_Query loops. No database hits happen until much later, so the only “wasted” overhead is WP filling query vars. WP_Query has a method called init that basically resets everything. Call it, then set whatever query variables you need. Then you’ll need to call parse_query again to set up the various conditionals.

<?php
add_action('pre_get_posts', 'wpse83187_reset_q');
function wpse83187_reset_q($query)
{
    if (!$query->is_main_query() /* other conditionals here! */) {
         return;
    }

    $query->init();

    // reset query vars here. eg:
    $query->set('post_type', 'product');

    // re-run validation and conditional set up.
    $query->parse_query();
}

Leave a Comment