問題描述

解決方案 HERE

我設置了一個名為 clientarea 的自定義帖子類型,並在管理區域中為它設置了多個自定義列 – 自定義列都是自定義元字段,可以從我的代碼中看到。我想按’Appointment Date’ 排序默認下降。

所有的列都可以正常工作,並且可以按預期手動排序,但是我無法獲得默認的排序順序。

如果我將默認排序字段更改為標準字段 (例如’title’),它的工作原理如下:當我嘗試將自定義列設置為默認排序順序時,它似乎不起作用。訂單工作 (即使使用自定義列,我也可以默認在 asc 和 desc 之間進行更改),但是它不會依次排列順序,因此在發佈自定義帖子的日期還原到排序。

我失蹤了什麼

我的代碼如下:

add_action( 'manage_posts_custom_column' , 'custom_columns', 10, 2 );

function custom_columns( $column, $post_id ) {
    global $wpdb;
    switch ( $column ) {
        case 'extranet_case_office':
            $get_office_ID = get_post_meta( $post_id, 'extranet_case_office', true );
            $get_office_name = $wpdb->get_results('SELECT post_title FROM `cn_bf_posts` WHERE `ID` = '.$get_office_ID);
            echo $get_office_name[0]->post_title;
            break;
        case 'extranet_appointment_date':
            echo date('d/m/Y',strtotime(get_post_meta( $post_id, 'extranet_appointment_date', true )));
            break;
        case 'extranet_appointment_type':
            echo get_post_meta( $post_id, 'extranet_appointment_type', true );
            break;
        case 'extranet_insolvency_practioner':
            $get_person_ID = get_post_meta( $post_id, 'extranet_insolvency_practioner', true );
            $get_person_name = $wpdb->get_results('SELECT post_title FROM `cn_bf_posts` WHERE `ID` = '.$get_person_ID);
            echo $get_person_name[0]->post_title;
            break;
        default:
            break;
    }
}

add_filter( 'manage_edit-clientarea_sortable_columns', 'my_sortable_clientarea_columns' );

function my_sortable_clientarea_columns( $columns ) {
    $columns['extranet_case_office'] = 'extranet_sort_office';
    $columns['extranet_appointment_date'] = 'extranet_sort_date';
    $columns['extranet_appointment_type'] = 'extranet_sort_type';
    $columns['extranet_insolvency_practioner'] = 'extranet_sort_IP';
    return $columns;
}

add_action( 'pre_get_posts', 'extranet_orderby' );

function extranet_orderby( $query ) {
    if( ! is_admin() )
        return;

    $orderby = $query->get( 'orderby');

    switch ( $orderby ) {
        case 'extranet_sort_office':
            $query->set('meta_key','extranet_case_office');
            $query->set('orderby','meta_value_num');
            break;
        case 'extranet_sort_date':
            $query->set('meta_key','extranet_appointment_date');
            $query->set('orderby','meta_value');
            break;
        case 'extranet_sort_type':
            $query->set('meta_key','extranet_appointment_type');
            $query->set('orderby','meta_value');
            break;
        case 'extranet_sort_IP':
            $query->set('meta_key','extranet_insolvency_practioner');
            $query->set('orderby','meta_value_num');
            break;
        default:
            break;
    }
}

add_action('pre_get_posts','clientarea_default_order');
function clientarea_default_order( $query ){
    if( $query->get('post_type')=='clientarea' ){
        if( $query->get('orderby') == '' )
            $query->set('orderby','extranet_sort_date');

        if( $query->get('order') == '' )
            $query->set('order','desc');
    }
}

最佳解決方案

來自 @birgire 的 StackExchange 上的 cross post 解決方案:

The problem is that you run the clientarea_default_order callback too late.

To fix that you only have to change the priority from the default one that’s 10:

add_action( 'pre_get_posts','clientarea_default_order'); 

to the priority of 9:

add_action( 'pre_get_posts','clientarea_default_order', 9 ); 

But you don’t actually need two pre_get_posts callbacks.

You can combine them:

Example #1

is_admin() && add_action( 'pre_get_posts', 'extranet_orderby' );      function extranet_orderby( $query )  {        // Nothing to do:       if( ! $query->is_main_query() || 'clientarea' != $query->get( 'post_type' )  )         return;      //-------------------------------------------       // Modify the 'orderby' and 'meta_key' parts     //-------------------------------------------       $orderby = $query->get( 'orderby');            switch ( $orderby )      {         case 'extranet_sort_office':             $query->set( 'meta_key', 'extranet_case_office' );             $query->set( 'orderby',  'meta_value_num' );             break;         case 'extranet_sort_date':             $query->set( 'meta_key', 'extranet_appointment_date' );               $query->set( 'orderby',  'meta_value' );             break;         case '':  // <-- The default empty case             $query->set( 'meta_key', 'extranet_appointment_date' );               $query->set( 'orderby',  'meta_value' );             break;         case 'extranet_sort_type':             $query->set( 'meta_key', 'extranet_appointment_type' );             $query->set( 'orderby',  'meta_value' );             break;         case 'extranet_sort_IP':             $query->set( 'meta_key', 'extranet_insolvency_practioner' );             $query->set( 'orderby', 'meta_value_num' );             break;         default:             break;     } } 

where we added a main query check and an empty switch case.

Example #2

Here’s another approach, without the switch part (PHP 5.4+):

is_admin() && add_action( 'pre_get_posts', 'extranet_orderby' );  function extranet_orderby( $query ) {     // Nothing to do     if( ! $query->is_main_query() || 'clientarea' != $query->get( 'post_type' )  )         return;      //-------------------------------------------       // Modify the 'orderby' and 'meta_key' parts     //-------------------------------------------       $orderby = strtolower( $query->get( 'orderby') );       $mods = [         'office' => [ 'meta_key' => 'extranet_sort_office',           'orderby' => 'meta_value_num' ],         'date'   => [ 'meta_key' => 'extranet_appointment_date',      'orderby' => 'meta_value'     ],         ''       => [ 'meta_key' => 'extranet_appointment_date',      'orderby' => 'meta_value'     ],         'type'   => [ 'meta_key' => 'extranet_sort_type',             'orderby' => 'meta_value_num' ],         'ip'     => [ 'meta_key' => 'extranet_insolvency_practioner', 'orderby' => 'meta_value_num' ],     ];     $key = 'extranet_sort_' . $orderby;     if( isset( $mods[$key] ) )     {         $query->set( 'meta_key', $mods[$key]['meta_key'] );         $query->set( 'orderby',  $mods[$key]['orderby']  );     } } 

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。