WP_Query->is_main_query()
method source (which function of same name calls) is very short and simple:
function is_main_query() {
global $wp_the_query;
return $wp_the_query === $this;
}
The main query is the query that is stored in $wp_the_query
global. But what is that global? When WP sets up main query it stores it in two places: $wp_the_query
and $wp_query
. Latter is more known because that variable is what you commonly use to work with main query and what query_posts()
changes.
However query_posts()
works like this:
function query_posts($query) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
It break link between $wp_query
and $wp_the_query
. And the reverse can be performend by wp_reset_query()
to re-establish that:
function wp_reset_query() {
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
wp_reset_postdata();
}
So main query is the one that WP set up during core load.
It is typically what $wp_query
holds, unless it was modified not to be main query anymore.