Skip to main content
Source Link
Z. Zlatev
  • 1.2k
  • 6
  • 16

Orderby custom field meta value ASC and then by date DESC

I need to allow post ordering in certain categories. One of the sorting options is a custom field meta value. First problem is that not all posts have that meta assigned and i need to order these by date (default).

Another problem is that meta field should use ASC order and the rest DESC.

My code so far

In Template File:

$request = $_REQUEST;
global $query_string;
parse_str( $query_string, $qs_arr );

switch ( $request['sort'] ) {

    case 'title':
        $qs_arr['orderby'] = 'title';
        $qs_arr['order'] = 'ASC';
        break;
    case 'publisher':
        $qs_arr['meta_key'] = 'discography_publisher';
        $qs_arr['orderby'] = 'meta_value';
        
        add_filter( 'posts_orderby', 'sort_posts_orderby' );
        add_filter( 'get_meta_sql', 'sort_get_meta_sql' );
        add_filter( 'posts_where' , 'sort_posts_where' );
        break;
}

if ( isset( $request['sort'] ) ) { query_posts( $qs_arr ); }

functions.php

function sort_get_meta_sql( $meta_sql ) {
    $meta_sql['join'] = " LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'discography_publisher') ";
    return $meta_sql;
}

function sort_posts_where( $where ) {
    //here i remove the last statement "wp_postmeta.meta_key = 'discography_publisher' " so query return all posts in category 
    $explode = explode( 'AND', $where );
    array_pop( $explode );
    return implode( 'AND', $explode );
}



function sort_posts_orderby( $orderby ) {
    $orderby = 'COALESCE(wp_postmeta.meta_value, wp_posts.post_date) DESC';
    return $orderby;
}