I’m trying to order the main query on the ‘Jobs’ post type archive page. I want to order them by a meta_key so the ones which have a value (i.e. are checked as Featured’) are shown first. Here’s what I have at the moment..
function featured_jobs_order( $orderby ) {
if( !is_post_type_archive('jobs') ) {
return $orderby;
}
global $wpdb;
$orderby = $wpdb->postmeta . '.meta_value DESC, ' . $orderby;
return $orderby;
}
add_filter('posts_orderby', 'featured_jobs_order' );
function change_jobs_query( $query ) {
if ( is_post_type_archive( 'jobs' ) ) {
$query->set( 'meta_key', 'featured' );
return;
}
}
add_action( 'pre_get_posts', 'change_jobs_query', 1 );
At the moment it only brings back the ones that are featured and doesn’t bring back the rest at all.
Cheers,
Steve
That happens because of the way WordPress structures the MySQL queries, and the way
posts
joinspostmeta
. If a post doesn’t have a value infeatured
, it won’t join. Here are two options for you:Update the way you’re storing
featured
to store the value regardless (either ‘1’ or ‘0’). Ensure that every post has a value forfeatured
and they’ll all show up. If you’re using a checkbox to set the value, this is very easy: put a hidden field above it with the same name as the checkbox and the “not set” value. If the checkbox is checked, it will override the hidden field.Use two loops in this archive page. You can use the technique I suggested in this question to ensure that your featured posts don’t show up twice.
I would suggest that rather than try to intercept the query through
functions.php
, try creating an archive page for the jobs post type namedarchive-jobs.php
in your template directory. If it is named like this, WordPress will associate it as the archive page for the custom post type.Then, modify the loop query on that page: (See the examples for WP_Query Order & Orderby Parameters)