How do I order by multiple custom fields using wp_query?

I had the same problem and could not find a way to make this work with wp_query alone. Instead, I caught the posts_clauses filter and stuck my order_by there. This also meant doing a few joins.

Basically, you set a function to catch the posts_clauses (or one of the more restrictive query filters; but let’s just use this for now), and then within that JOIN to the post_meta table for the fields you need, then order by them.

The important thing is to set up something to then remove the query filter. You could do it at the end of the function that catches it, but I have it separate in my plugin, so I’m going to stick with that. The ‘wp’ event works fine here.

add_filter('posts_clauses', 'filterMarkets')
add_filter('wp', 'removeQueryFilter');

public static function removeQueryFilter() {
  remove_filter('posts_clauses', 'filterMarkets');
}

public static function filterMarkets($clauses, $wp_query) {
global $wpdb;

$clauses['join'] .=<<<SQL
JOIN {$wpdb->postmeta} AS title_meta ON title_meta.post_id = {$wpdb->posts}.ID AND
title_meta.meta_key = 'fest_sortby'
JOIN {$wpdb->postmeta} AS start_date_meta ON start_date_meta.post_id = {$wpdb->posts}.ID
AND start_date_meta.meta_key = 'fest_market_start_date'
SQL;

  $clauses['orderby'] .= " title_meta.meta_value ASC";
  $clauses['orderby'] .= " start_date_meta.meta_value ASC";
}
return $clauses;

}

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)