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?
Yay!
So
pre_get_posts
filters aWP_Query
object which means anything you could do viaquery_posts()
you can do via$query->set()
and$query->get()
. In particular we can make use of themeta_query
attribute (see Codex):But.. this replaces the original ‘meta query’ (if it had one). So unless you want to completely replace the original meta query, I suggest:
This way we add our meta query alongside existing meta queries.
You may/may not want to set the
relation
property of$meta_query
toAND
orOR
(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.In response @Carlisle, if you want exclude the most 5 recent posts marked featured, you could do the following. Change the posts_per_page to how many you want to exclude, and the meta_query to how you are designating the featured category.
I want to post my temporary solution for featured posts in case some people may make use of it. I don’t use
pre_get_posts
hook here but notquery_posts
either. The problem is that I have to play with the main query and have to run a piece of sql query.I would be happy if any experts could check the code and let me know whether it’s OK and will not cause any performance issues. It will also be great if anyone has a better approach and share it with us.
Create featured posts query
Create the main query, exclude the posts which has the featured meta_key, limit the exclusion to 5 most recent posts and show all others.