• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Be Devious

Friendly, helpful, personal web services. Seriously.

  • Home
  • Services
  • Portfolio
  • Testimonials
  • Contact
  • Blog
  • Portal

Sorting WordPress Queries By Multiple Criteria

June 8, 2020 by Dominic Vermeulen-Smith Leave a Comment

Sorting posts and custom post types in WordPress has been made pretty easy when compared to the old days of having to write custom SQL queries thanks to the WP_Query class. Later updates to the class methods to allow arrays and multiple values have helped even further. But when using the class in such a way, you can still end up in a bit of a muddle.

I was recently working on a project that included listing classified ads that were initially added by the administrator but could subsequently be managed by a user if they joined the site and paid a subscription. I was under an NDA for this one, so I’ll need to create a new scenario to illustrate what was needed here, let’s say we’re talking about camp sites.

What were the sorting requirements?

On the site, the client wanted to, generally, list the camp sites that appeared in a given set of search results in a random order, so as not to give specific priority to any of them.

One of the benefits of signing up and paying to manage your own listing, however, was that you would be prioritised in any search results you appeared in and so would need to be listed at the top.

Subsequently, the client found that camp site owners were not always adding a featured image to their listing, and so to further encourage this, listings with a featured image would appear higher than those without.

So, the requirements were to sort like this:

  • Show listings for paying clients above listings with no paying client
  • Show those with featured images above those without featured images
  • Otherwise, show them in a random order

The Code

For this, we need to use the good old pre_get_posts hook to alter the query.

First off, we set up the function and hook and ensure that this is only run when we want it to be:

function custom_sorting( $query ) {

  //don't edit the query if we're not dealing with the main query for
  //the post-type-slug post type and we're not in the admin area
  if( ! is_post_type_archive( 'post-type-slug' ) || is_admin() || $query->is_main_query() ) {
    return;
  }

}

add_action( 'pre_get_posts' , 'custom_sorting' , 100 );

We’re then going to add our sorting for those who have paid. NB. it’s elsewhere in the code that listings of paying members have a “1” stored in the wp_posts_meta table under the meta_key “is-active”, and ask the order by attribute to sort by this value.

Happy days.

function custom_sorting( $query ) { 

  //don't edit the query if we're not dealing with the main query for
  //the post-type-slug post type and we're not in the admin area
  if( ! is_post_type_archive( 'post-type-slug' ) || is_admin() || $query->is_main_query() ) {
    return;
  }

  //sort by the meta value is-active in a descending order, i.e. those with a 1 before those without
  $query->set( 'meta_key' , 'is-active' );
  $query->set( 'orderby' ,  'meta_value_num' );
  $query->set( 'order' , 'DESC' );

}

add_action( 'pre_get_posts' , 'custom_sorting' , 100 );

OK, so that was nice and easy, but, now that we’ve used the order and orderby parameters, how are we going to add more criteria and sort orders for them?

There’s a couple of steps to this:

  • Update the meta query array to filter for posts with AND without featured images
  • Update the order parameter to the array format
  • Remove the order parameter
function custom_sorting( $query ) {   

  //don't edit the query if we're not dealing with the main query for
  //the post-type-slug post type and we're not in the admin area
  if( ! is_post_type_archive( 'post-type-slug' ) || is_admin() || $query->is_main_query() ) {
    return;
  }

  //add a query to filter for posts that do AND don't have a _thumnail_id value
  //if you don't add the NOT EXISTS clause you will lose any posts without featured images
  $meta_query = array(
    'relation' => 'OR',
    //note that you must name elements you wish to filter by
    'has-image' => array(
      'key' => '_thumbnail_id',
      'compare' => 'EXISTS',
    ),
    'has-no-image' => array(
      'key' => '_thumbnail_id',
      'compare' => 'NOT EXISTS',
    ),
  );

  $query->set( 'meta_query' , $meta_query );

  $query->set( 'meta_key' , 'is-active' );
  $query->set( 'orderby' , array( 
    'meta_value_num' => 'DESC', 
    'has-image' => 'DESC'*, 
    'rand' => 'rand' 
  ));

}

add_action( 'pre_get_posts' , 'custom_sorting' , 100 );

And there you have it, you can now sort by multiple criteria in WordPress.

Links:

  • https://codex.wordpress.org/Class_Reference/WP_Query

Featured Image Credit:

  • Sophie Elvis @ Unsplash

Share this:

  • Facebook
  • Twitter
  • LinkedIn
  • Reddit

Filed Under: Coding

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Stay in touch

*We won't share your information and it'll only be used to send you internet goodies!

Recent Posts

  • Password Reset via the WordPress REST API
  • Sorting WordPress Queries By Multiple Criteria
  • How To Use GTMetrix to Test The WordPress Admin Area
  • Not Another WordPress REST API Post
  • Speed Up WordPress Websites – 6 Essential Tips

Recent Comments

  • Password Reset via the WordPress REST API - Be Devious on Not Another WordPress REST API Post
  • Dominic Vermeulen-Smith on Not Another WordPress REST API Post
  • Dave Spencer on Not Another WordPress REST API Post

Archives

  • September 2020
  • June 2020
  • August 2017
  • July 2016
  • June 2016

Categories

  • BeDeViouS
  • Coding
  • General
  • Hosting
  • Opinion
  • REST API
  • Security
  • SEO
  • Uncategorized
  • Website Performance
  • Home
  • Contact
  • Privacy Policy

Copyright © 2021 BDEVIOUS LTD. Registered in England and Wales 10124924