I need to block some accesses to search results not the whole page, just the results.

The problem is, I need the search SQL query to not happen AT ALL. (I can conditionaly hide the output loop template very easily, I'm just not sure SQL is not happening).

Where would I prevent such thing (I assume some filter/action hook I just could not find the right one)?

EDIT: Please note, that the page needs to be loaded and displayed, otherwise I would proceed with request blocking approach like template_redirect

  • Can you please give some context on what is on the page that still needs to be displayed if you still need it to show and not redirect? it matters depending on what route you go.
    – Elgoots
    Dec 7, 2019 at 5:01
  • @Elgoots basically everything else BUT not the results - instead of them, there should be an notice message.
    – jave.web
    Dec 9, 2019 at 15:59

1 Answer 1


It's possible to avoid SQL execution in WP_Query with the posts_pre_query filter.

It's e.g. used by plugins to outsource the default search to 3rd party search engines.

Here's an example how we can override the main search query on the front-end, with an empty posts array and avoid running the SQL search query:

add_filter( 'posts_pre_query', function( $posts, \WP_Query $query ){
    if( $query->is_search() && $query->is_main_query() && ! is_admin() ) {
        return array();
    return $posts;
}, 10, 2 );

Since we're returning an empty array, I don't think we need to adjust the $query->found_posts or $query->max_num_pages as they are zero by default.

  • This seems like the way, any ideas how would one differentiate between "nothing found" and "query blocked" (both empty posts array right?) ?
    – jave.web
    Dec 10, 2019 at 0:53
  • @jave.web You could throw a custom exception instead of returning the empty array and then catch that to differentiate.
    – kero
    Dec 10, 2019 at 9:03
  • @jave.web One way could be to set a custom query variable with the set() method if WP_Query within the posts_pre_query callback and then check it within the template with the get() method.
    – birgire
    Dec 10, 2019 at 23:05
  • 1
    @birgire that seems like a reasonable solution :)
    – jave.web
    Dec 11, 2019 at 16:55
  • 1
    posts_pre_query seems to be the one directly affecting if query is done or not, also interesting fact is that it is not affected by 'suppress_filters' query settings unlike almost every other filter in get_posts() => ACCEPT. Sidenote: pre_get_posts is an action NOT a filter - you can set stuff there, but not filter the actual query :)
    – jave.web
    Dec 13, 2019 at 13:09

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.