Come impostare l'ordinamento predefinito in admin per una colonna personalizzata in un custom post type?
SOLUZIONE DISPONIBILE QUI
Ho configurato un custom post type chiamato clientarea e ho impostato diverse colonne personalizzate nell'area amministrativa - le colonne personalizzate sono tutti campi meta personalizzati, come si può vedere dal mio codice. Vorrei ordinare per 'Data Appuntamento' in ordine decrescente per impostazione predefinita.
Tutte le colonne funzionano correttamente e possono essere ordinate manualmente come previsto, ma non riesco a far funzionare l'ordinamento predefinito.
Se cambio il campo di ordinamento predefinito con un campo standard (es. 'title') funziona come previsto; sembra non funzionare solo quando sto cercando di impostare una colonna personalizzata come ordinamento predefinito. L'ordine funziona (cioè posso alternare tra asc e desc per impostazione predefinita anche con una colonna personalizzata), ma non rileva l'orderby quindi torna a ordinare per data di pubblicazione del custom post.
Cosa mi sta sfuggendo?
Il mio codice è il seguente:
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');
}
}

Soluzione da un cross post su StackExchange di @birgire:
Il problema è che esegui la callback
clientarea_default_order
troppo tardi.Per risolverlo, devi solo cambiare la priorità da quella predefinita che è
10
:add_action( 'pre_get_posts','clientarea_default_order');
a una priorità di
9
:add_action( 'pre_get_posts','clientarea_default_order', 9 );
Ma in realtà non servono due callback
pre_get_posts
.Puoi combinarle:
Esempio #1
is_admin() && add_action( 'pre_get_posts', 'extranet_orderby' ); function extranet_orderby( $query ) { // Niente da fare: if( ! $query->is_main_query() || 'clientarea' != $query->get( 'post_type' ) ) return; //------------------------------------------- // Modifica le parti 'orderby' e 'meta_key' //------------------------------------------- $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 '': // <-- Caso vuoto predefinito $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; } }
dove abbiamo aggiunto un controllo per la query principale e un caso vuoto nello switch.
Esempio #2
Ecco un altro approccio, senza la parte
switch
(PHP 5.4+):is_admin() && add_action( 'pre_get_posts', 'extranet_orderby' ); function extranet_orderby( $query ) { // Niente da fare if( ! $query->is_main_query() || 'clientarea' != $query->get( 'post_type' ) ) return; //------------------------------------------- // Modifica le parti 'orderby' e 'meta_key' //------------------------------------------- $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'] ); } }
