Sorting posts that has a meta value first then the rest of the posts

Im using the pre_get_posts hook to customize my query for a custom post type archive.

Some of the posts for this custom post type have a meta key mp_micropub_accredited with the meta value of 1 and others don’t have this meta key set.

I use the following code,

function micropubs_filter_posts( $query ) {
    if ( !is_admin() && $query->is_post_type_archive( 'micropubs' ) && $query->is_main_query() ) {
        $query->set( 'posts_per_page', 5 );
        $accredited = filter_input( INPUT_GET, 'orderby', FILTER_SANITIZE_STRING ); 
        if ( empty( $accredited ) )
            return;
        if ( $accredited === 'accredited' ) {
            $query->set( 'meta_key', 'mp_micropub_accredited' );
            $query->set( 'orderby', 'meta_value_num' );
        }
    }
}
add_action( 'pre_get_posts', 'micropubs_filter_posts' );

So when i locate to this address in my browser it displays only the posts with the meta key set and no other posts.

http://localhost/site/post-type-archive/?orderby=accredited

How is it possible to include all the other posts that don’t have the mp_micropub_accredited meta key set but are displayed after the ones that are?

Your help much appreciated. 🙂

1 Answer
1

I would suggest you when you are updating meta values with 1 update rest with 0.
I mean set the key in all posts with 1 or 0 to avoid the complex query.

You can still do it with a simple script. It will check if key doesn’t exist then update it with 0. So your current code will work like charm.

OR

You can use compare with NOT EXISTS

$meta_query = array(
    'relation' => 'OR',
    array(
        'key' => 'mp_micropub_accredited',
        'value' => 1
    ),
    array(
        'key' => 'mp_micropub_accredited',
        'compare' => 'NOT EXISTS'
    )
);
$query->set( 'meta_query', $meta_query );
$query->set( 'orderby', 'meta_value_num' );

Note: This solution will only work with WP >= 3.9 as NOT EXISTS only works with 3.5 and greater and there was a bug with NOT EXISTS which has been fixed in 3.9!

Leave a Comment