Ordering by meta_key

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.

Read More

Cheers,
Steve

Related posts

Leave a Reply

2 comments

  1. That happens because of the way WordPress structures the MySQL queries, and the way posts joins postmeta. If a post doesn’t have a value in featured, it won’t join. Here are two options for you:

    1. Update the way you’re storing featured to store the value regardless (either ‘1’ or ‘0’). Ensure that every post has a value for featured 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.

    2. 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.

  2. I would suggest that rather than try to intercept the query through functions.php, try creating an archive page for the jobs post type named archive-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)

    <?php query_posts( array( 'post_type' => 'jobs', 'orderby' => 'meta_value', 'meta_key' => 'featured' ) ); ?>
    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
        <?php the_content(); ?>
    <?php endwhile; else: ?>
        <p>Sorry, no posts matched your criteria.</p>
    <?php endif; ?>