Ordinare i termini per term_order
Contesto
- Tipo di Post: Resources
- Tassonomia: Media Type, Termine: Audio
- Tassonomia: Series
Il seguente codice mostra una lista univoca della tassonomia personalizzata "Series"
Voglio ordinare la lista per term_order, ma non funziona. Qualche suggerimento?
Il sito. Attualmente è ordinato per ID
<?php
// Array per i dati del post
$post_data = array();
$my_query = new WP_Query( array(
'post_type' => 'resource',
'posts_per_page' => -1,
'media_type' => 'audio'
)
);
if ( $my_query->have_posts() ) {
while ( $my_query->have_posts() ) {
$my_query->the_post();
$post_data[] = get_the_ID();
}
}
// Inizia con qualsiasi ID desideri avere da Media Type
$audio = 16;
// Ottieni tutti gli ID dei post per quel termine
$post_ids = get_objects_in_term( $audio, 'media_type', array('post_status' => 'publish') );
// Quindi ottieni i termini della serie per quegli ID dei post
$terms = wp_get_object_terms( $post_data, 'series', array('fields' => 'ids', 'orderby' => 'menu_order' ) );
$result = array_values( array_unique($terms) );
?>
<?php
$a = $result;
foreach ($a as $v) {
$term = get_term( $v, 'series' );
$name = $term->name;
$slug = $term->slug;
echo '<div class="resource-item"><a href="'.get_term_link($slug, 'series').'" title="'.$name.'"><div class="play"></div><li>'.$name.'</li></a></div>';
}
?>

Poiché questo è uno dei primi risultati su Google e nessuna delle soluzioni precedenti ha funzionato per me, questo metodo sembra restituire i termini in un ordine corrispondente alla loro visualizzazione nell'amministrazione...
get_terms([
'taxonomy' => 'whatever_you_want', // Sostituire con la tassonomia desiderata
'meta_key' => 'order', // Chiave meta che contiene l'ordine
'orderby' => 'meta_value_num' // Ordinamento per valore numerico del meta
]);
Nel caso possa aiutare qualcuno, WordPress memorizza un valore nella tabella termmeta con la chiave 'order' che rappresenta la posizione di visualizzazione nei menu di amministrazione. Ovviamente dovrebbe essere adattato se si desidera eseguire query su altri meta contemporaneamente.

Invece di menu_order
prova term_order
.
Secondo la documentazione sul Codex, wp_get_object_terms
supporta:
- name
- count
- slug
- term_group
- term_order e
- term_id

@izharbuen Per favore accetta questa risposta cliccando sul segno di spunta accanto ad essa. Grazie :-)

@PieterGoosen izharbuen ha detto che non funziona, quindi sarebbe sbagliato contrassegnare questa come la risposta corretta. Posso confermare che impostare orderby
a term_order
non funziona. Mi sto scervellando per capire il perché.

term_order
non è un ordinamento per i termini all'interno di una tassonomia. È un ordinamento per i termini all'interno di un oggetto (post).
https://developer.wordpress.org/reference/classes/wp_term_query/__construct/ afferma:
A meno che $object_ids non sia vuoto, 'term_order' viene trattato allo stesso modo di 'term_id'.
Per chi sta cercando di ordinare i termini per un oggetto in base a term_id
, è necessario fornire object_ids alla query.
Per tutti gli altri che pongono questa domanda, cercando di ordinare una lista di termini, non usate term_id
. Invece aggiungete un valore di meta al termine e ordinate in base a quello.
get_terms([
'taxonomy' => 'my_taxonomy',
'meta_key' => 'order',
'orderby' => 'meta_value_num'
]);

wp_term_query
non accetta term_order
come uno dei parametri orderby. Quindi devi forzatamente aggiungere quell'opzione alla variabile di query dei termini aggiungendo i seguenti snippet al tuo functions.php.
function wpcf_filter_terms_order( $orderby, $query_vars, $taxonomies ) {
return $query_vars['orderby'] == 'term_order' ? 'term_order' : $orderby;
}
add_filter( 'get_terms_orderby', 'wpcf_filter_terms_order', 10, 3 );
Dopo aver aggiunto i snippet sopra, se eseguirai qualcosa come mostrato di seguito, otterrai i termini ordinati per term_order.
$terms = get_terms('category', array(
'orderby' => 'term_order',
'order' => 'ASC'
));
Secondo approccio, se vuoi ottenere i termini per term_order globalmente e in tutto WordPress, aggiungi semplicemente i seguenti snippet a functions.php.
function uc_get_terms_orderby($orderby, $args){
return 't.term_order';
}
add_filter('get_terms_orderby', 'uc_get_terms_orderby', 10, 2);

Molti anni dopo,
Puoi aggiungere questo codice nel tuo functions.php:
/**
* Filtra l'ordinamento dei termini per utilizzare term_order quando specificato
*/
function wpcf_filter_terms_order( $orderby, $query_vars, $taxonomies ) {
return $query_vars['orderby'] == 'term_order' ? 'term_order' : $orderby;
}
// Aggiunge il filtro per modificare l'ordinamento dei termini
add_filter( 'get_terms_orderby', 'wpcf_filter_terms_order', 10, 3 );
Questo codice forza WordPress a utilizzare l'argomento orderby => term_order nella tua query di termini.

Questa è un'idea
Ma l'ho realizzata pensando di ordinare un elenco sul front end
È necessario modificare la tabella "{prefix}term_taxonomy", creando il campo "term_order". Vedi la funzione O_term_update_db():
Nel tuo function.php
<?php
function O_term_update_db(){
global $wpdb;
global $term_db_version;
$term_db_version = "1";
$charset_collate = $wpdb->get_charset_collate();
if(get_site_option( 'O_term_db_version' ) < $term_db_version):
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$wpdb->query( "ALTER TABLE $wpdb->prefix .'term_taxonomy' ADD `term_order` INT (11) NOT NULL DEFAULT 0;" );
update_site_option( 'O_term_db_version', $term_db_version);
endif;
}
add_action('init','O_term_update_db');
?>
Questa funzione si riferisce al database:
Nel tuo functions.php
<?php
function O_taxonomy_filter_by_order($taxonomy){
global $wpdb;
$terms = $wpdb->get_results("
SELECT t.*, tt.*
FROM ".$wpdb->prefix."term_taxonomy AS tt
JOIN ".$wpdb->prefix."terms AS t
ON t.term_id = tt.term_id
WHERE tt.taxonomy = '".$taxonomy."'
ORDER BY tt.term_order ASC
",ARRAY_A);
return $terms;
}
?>
Questa funzione viene utilizzata per aggiornare la tabella via Ajax:
Nel tuo function.php
<?php
if(!function_exists('O_updating_data_term_reorder')){
function O_updating_data_term_reorder() {
check_ajax_referer('o-nonce', 'security');
global $wpdb;
$terms_ID = $_POST['each_term'];
$new_order = 0;
foreach($terms_ID as $key => $ID):
$term_ID = $ID['term'];
$new_order++;
$result = $wpdb->update($wpdb->prefix.'term_taxonomy', array('term_order' => $new_order), array('term_id' => $term_ID));
if(is_wp_error($result)) {
echo json_encode(array('save'=>false, 'message'=> 'ERRORE: '.$result->get_error_message()));
exit();
}
endforeach;
echo json_encode(array('save'=>true, 'count'=>$new_order));
die();
}
add_action( 'wp_ajax_o_update_term_reorder', 'O_updating_data_term_reorder' );
}
?>
draggable-ajax.js:
(function($) {
"use strict";
//jQuery Sortable è richiesto http://api.jqueryui.com/sortable/
//Chiama "wp_enqueue_script('jquery-ui-sortable');" nel tuo wp_enqueue_scripts
$('.js-draggable-items > .draggable-column').sortable({
connectWith: '.draggable-column',
items: '.draggable-item',
dropOnEmpty: true,
opacity: .75,
handle: '.draggable-handler',
placeholder: 'draggable-placeholder',
tolerance: 'pointer',
start: function(e, ui){
ui.placeholder.css({
'height': ui.item.outerHeight(),
'margin-bottom': ui.item.css('margin-bottom')
});
}
});
$(document).on( "click","#btn-reorder-terms", function() {
var each_term_list = [];
$('.draggable-item').each(function(){
each_term_list.push({
term: $(this).attr('data-draggable-id'),
});
});
var data = {
'action' : 'o_update_term_reorder',
'each_term' : each_term_list,
'security' : actions_vars.nonce
};
$.ajax({
type: 'POST',
dataType: 'json',
cache: false,
url: actions_vars.ajaxurl,
data: data,
success: function(data) {
if(data.save === true){
//messaggio di successo qui
alert('Fatto');
}else{
//messaggio di errore qui
alert('Qualcosa è andato storto');
}
},
error: function(errorThrown) {
console.log(data);
}
});
});
})(jQuery);
Nel tuo elenco front-end prova questo:
<?php
$terms = O_taxonomy_filter_by_order('your_taxonomy');
?>
<button type="button" class="btn btn-primary" id="btn-reorder-terms">Salva</button>
<div class="col-md-12 js-draggable-items">
<div class="row draggable-column">
<?php
foreach($terms as $key => $term):
$ID = $term['term_id'];
$name = $term['name'];
$order = $term['term_order'];
$description = $term['description'];
$link = get_category_link($ID);
?>
<div class="draggable-item" data-draggable-id="<?php echo $ID;?>" data-term-order="<?php echo $order;?>">
<div class="col-md-2 draggable-handler"><i class="si si-cursor-move"></i></div>
<div class="col-md-10"><?php echo $name;?></div>
</div>
<?php
endforeach;
?>
<div>
<div>
