How to order custom post type by multiple custom fields?

How to display posts with ‘Event’ custom type ordered by ‘Start_Hour’ and then by ‘Start_Minute’?

‘Start_Hour’ and ‘Start_Minute’ are numeric custom fields.

I tried this, but it doesn’t work:

$args = array(
  'post_type'=>'Events',
  'orderby' => 'meta_value',
  'meta_key' => 'Start_Hour Start_Minute',
  'order' => 'ASC'
);
$loop = new WP_Query( $args );

2 s
2

when you use 'meta_key' => 'Start_Hour Start_Minute' then the query looks for posts with a custom field named Start_Hour Start_Minute together so that is why its not working for you.

But there is a way to order by multiple custom fields using posts_orderby filter hook, so first create a function that will add your orderby fields like so:

function orderbyreplace($orderby ) {
  global $wpdb;
    return str_replace($wpdb->prefix.'postmeta.meta_value', 'mt1.meta_value, mt2.meta_value ASC', $orderby);
}

then set your args as:

$args = array(
  'post_type'=>'Events',
  'orderby' => 'meta_value',
  'meta_key' => 'Start_Hour',
  'meta_query' => array(
        array(
            'key' => 'Start_Hour',
            'value' => '0',
            'type' => 'NUMERIC',
            'compare' => '!='
        ),
        array(
            'key' => 'Start_Minute',
            'value' => '0',
            'type' => 'NUMERIC',
            'compare' => '!='
        )
    )
);

See how i use the meta_query which will join both custom fields and all that is left is to hook your orderbyreplace function just before your query so:

add_filter('posts_orderby','orderbyreplace');
$loop = new WP_Query( $args );
remove_filter('posts_orderby','orderbyreplace');

Leave a Comment