I see many people prefer to use pre_get_posts
hook instead of query_posts
. The code below works and shows all posts which have meta key “featured”
function show_featured_posts ( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'meta_key', 'featured' );
$query->set( 'meta_value', 'yes' );
}
}
add_action( 'pre_get_posts', 'show_featured_posts' );
But I want the posts which have ‘featured
‘ meta_key to be excluded from the main query. Is there an easy way for this?
I see many people prefer to use pre_get_posts hook instead of query_posts
Yay!
So pre_get_posts
filters a WP_Query
object which means anything you could do via query_posts()
you can do via $query->set()
and $query->get()
. In particular we can make use of the meta_query
attribute (see Codex):
$meta_query = array(
array(
'key'=>'featured',
'value'=>'yes',
'compare'=>'!=',
),
);
$query->set('meta_query',$meta_query);
But.. this replaces the original ‘meta query’ (if it had one). So unless you want to completely replace the original meta query, I suggest:
//Get original meta query
$meta_query = $query->get('meta_query');
//Add our meta query to the original meta queries
$meta_query[] = array(
'key'=>'featured',
'value'=>'yes',
'compare'=>'!=',
);
$query->set('meta_query',$meta_query);
This way we add our meta query alongside existing meta queries.
You may/may not want to set the relation
property of $meta_query
to AND
or OR
(to return posts that satisfy all, or at least one, meta queries).
* Note: This type of query will return posts with the ‘featured’ meta key, but whose value is not yes
. It will not include posts where the ‘featured’ meta key doesn’t exist. You’ll be able to do this in 3.5.