0

The function below limits the search results to posts only.

function exclude_pages_from_search_results( $query ) {
    if ( $query->is_main_query() && $query->is_search() ) {
        $query->set( 'post_type', array( 'post' ) );
    }    
}

Should $query->be used with conditional tags such as is_home(), is_search()? If not, why and if yes, why?

1 Answer 1

1

As background, there are functions in WordPress that tell you certain things about the main query. For example, is_search(), is_archive() etc. will tell you whether the main query is a search query, or an archive query respectively. These typically, but not necessarily, line up with where certain templates will be used.

You use these functions if you want to know this information about the main query, and therefore know what kind of page you're looking at. However, note that the main query is an instance of WP_Query, but developers can create their own queries by creating their own instances of WP_Query.

Instances of the WP_Query object have equivalents of these conditional functions as methods. You can use these methods if you want to know the same thing about any of those specific queries, even if it's not the main query. For example (and assuming we are not on the search page):

$query = new WP_Query( array( 's' => 'Search term' ) );

var_dump( $query->is_search() ); // true
var_dump( is_search() ); // false

In fact, most conditional functions related to queries are just aliases for calling those methods on the main query. For example, is_archive() is exactly the same as this:

global $wp_query;
return $wp_query->is_archive();

So you use those functions as methods (i.e. with $query->) if you need to know if that query matches that condition. Or you use the naked function to check if the main query matches that condition.

Note that there's nothing special about $query->. $query is just a variable containing an instance of WP_Query. So when doing that check you need to substitute $query with an instance of WP_Query

When it comes to using pre_get_posts, be aware that this action is applied to all queries on a page, not just the main query. When you add an action to that hook, the query that the hook is currently being applied to will be passed to the callback as the first argument, so you should check the conditions against that variable to only apply changes to queries that match the condition.

8
  • Thanks. Have I understood you correctly that it should be used only if $query->is_main_query() is called?
    – Ryan
    Commented Jul 18, 2021 at 7:43
  • No. You should use it whenever you want to use one of the main conditional functions, unless you want to affect all queries. Commented Jul 18, 2021 at 7:52
  • Do you mean if I have a function that returns return ($post_type === 'post') && ( is_archive() || is_home() || is_single() ); it should instead be return ($post_type === 'post') && ( $query->is_archive() || $query->is_home() || $query->is_single() );?
    – Ryan
    Commented Jul 18, 2021 at 7:55
  • That example is not the same as your original question. Your original question is using the $query passed to pre_get_posts. The example in your comment seems unrelated, and it would depend on what the function is for and where $query comes from. My answer only applies to when you're filtering queries, like in your original question. Commented Jul 18, 2021 at 8:11
  • It is indeed different as I'm attempting to understand when query-> should be used. Have I understood you correctly, that it should only be used for all conditional tags when using pre_get_posts?
    – Ryan
    Commented Jul 18, 2021 at 8:36

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.