I have the following query which I call in my taxonomy.php template via query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);
This function works perfectly. However after reading codex for query posts it mentioned pre_get_posts as a preferred way to alter the default query. Would the pre_get_posts be more efficient then my wp_query function below?
If so how would I construct the pre_get_posts and pass my variable and query below?
function my_custom_query($posttype, $poststatus, $paidvalue, $taxtype, $geo, $brands) {
global $wp_query;
$wp_query = new WP_Query();
$args = array(
'post_type' => $posttype,
'post_status' => array($poststatus),
'orderby' => 'rand',
'posts_per_page' => 30,
'meta_query' => array(
array(
'key' => 'wpcf-paid',
'value' => array($paidvalue),
'compare' => 'IN',
)
),
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => $taxtype,
'field' => 'slug',
'terms' => $geo
),
array(
'taxonomy' => 'brands',
'field' => 'slug',
'terms' => $brands
)
)
);
return $wp_query->query($args);
}
pre_get_posts
will run the same query, so both will take same time. But, If you utilizepre_get_posts
action you will save one or more SQL queries. Right now, WordPress is running default query and then you run your query with this function which replace the results of the default query (resulting, default query is of no use). Below is how you can move your$args
toLate answer as the most upvoted answer will break your query and simply isn’t true in some major points.
The main WP_Query and it’s filters
First, WordPress internally uses
query_posts()
(a thin wrapper aroundWP_Query
that shouldn’t be used in themes or plugins) to do aWP_Query
. ThisWP_Query
is acting as the main loop/query. This query will run through a lot of filters and actions until the actual SQL query string is built. One of those ispre_get_posts
. Others areposts_clauses
,posts_where
, etc. that also allow you to intercept the query string building process.An in depth look at what happens inside core
Conclusion
If you really want to modify the main query, then you can use a wide variety of filters. Simply use
$query->set( 'some_key', 'some_value' );
to change data there or use$query->get( 'some_key' );
to retrieve data to do conditional checks. This will save you from doing a second query, as you’re altering the SQL query only.If you have to do an additional query, then go with a
WP_Query
object. This will add another query to the DB.Example
As answers always work better with an example, you here got one really nice one (props to Brad Touesnard), that simply extends the core object and therefore is pretty reusable (make a plugin out of it):
You can then run your second/additional query like you can see in the following example. Don’t forget to reset your query afterwards.
Please check out the answers at When to use WP_query(), query_posts() and pre_get_posts.
It is a great ressource if you have any doubts in mind.