Pre Get Posts – Difference between conditional() and $query->conditional()?

There’s a big difference… most of the times.

is_home(), just like any other conditional tag, check main query.

$query->condition() check the query object that is passed by action, that can be a a completely different query, because pre_get_posts is called for all queries.

As example, let’s assume you are viewing a singular post, and inside single.php you have:

$q = new WP_Query( array('nopaging'=>true) );

Now let’s assume in functions.php you have:

add_action('pre_get_posts', function ($query) {
    if( $query->is_home() ) {
       // conditional code
    }
} );

The hooked callback will run when action is triggered by both main query and secondary query.

However, for main query, conditional code does not run, because you are in singular post view, but when fired by secondary query conditional code will run, because that secondary query object is of home type.

So it’s not wrong to use $query->is_home() nor is_home(), they are just different, you should choose the one or the other based on the results you want to obtain.

However, when the query object passed by action is the main query, the 2 ways are identical, so if you want to check only main query objects, use one or another makes no difference:

function theme_pgp( $query ) {
    if ( ! $query->is_main_query() ) {
        return; // only main query
    }

    // here using is_home() or $query->is_home()
    // does not make any difference
}