I’m building the sorting functionality for a custom post type, and I have a custom meta value for “Featured” posts. This value is set when you tick the checkbox, otherwise it is not set.
Using the default orderby=meta_value
with meta_key=featured
makes it so that the screen only displays posts that have the meta key. If they don’t, they don’t even appear.
I want it so if it is not set, they do appear, but they appear last. I assume I need to use meta_query
instead, but I couldn’t get that to work either.
How do I allow empty, false, or non-existing meta keys in the WP_Query arguments?
My code is below. This is for sorting columns in the dashboard, so it is modifying the default WP Query args.
function featured_sortable_order( $vars ) {
if ( isset($vars['orderby']) && $vars['orderby'] == 'featured' ) {
$vars = array_merge( $vars, array(
'meta_key' => 'featured',
'orderby' => 'meta_value',
'order' => isset($vars['order']) ? $vars['order'] : 'asc',
) );
}
return $vars;
}
add_filter( 'request', 'featured_sortable_order' );
Completely edited after first publish
The problem is that to order for a meta value, WordPress need to
'meta_key'
in query is set to something.But if you set
'meta_key'
to something, then WordPress will add something liketo
WHERE
SQL clause; and something liketo
join
clauses. So query returns only the posts that has that meta query.Once you are working on backend, and you call
get_post_meta( $postid, 'featured', true)
for every post to show the column, is not a great performance issue call it 2 times thanks to WordPress cache on get meta function.So, the idea is get all the posts (without adding filter on meta key), then filter posts using
'posts_results'
hook and order posts looking at the ‘featured’ meta key.I’ll remove the filter just after having used it.
In addition, I add a filter on
'pre_get_post'
to use'ASC'
as default order if no order is set in the query:Why not giving all posts the meta attribute with a custom value?
I mean, you can set all posts to featured = no/false/0/low-numeric-valeu and then change to yes/true/1/high-numeric-values all those that should be featured and they will get ordered, won’t they?