Ordonează termenii după term_order
Context
- Tip Post: Resources
- Taxonomie: Media Type, Termen: Audio
- Taxonomie: Series
Următorul cod afișează o listă unică a taxonomiei personalizate "Series"
Vreau să ordonez lista după term_order, dar nu funcționează. Aveți sugestii?
Site-ul. În prezent este ordonat după ID
<?php
$post_data = array();
// Interogare pentru resurse audio
$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();
}
}
// Începe cu ID-ul dorit pentru Media Type
$audio = 16;
// Obține toate ID-urile postărilor pentru acel termen
$post_ids = get_objects_in_term( $audio, 'media_type', array('post_status' => 'publish') );
// Apoi obține termenii seriei pentru acele ID-uri de postări
$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>';
}
?>

Deoarece acesta este unul dintre primele rezultate pe Google și niciuna dintre soluțiile de mai sus nu au funcționat pentru mine, această metodă pare să returneze termenii în ordinea corespunzătoare afișării lor în panoul de administrare...
get_terms([
'taxonomy' => 'whatever_you_want', // Taxonomia dorită
'meta_key' => 'order', // Cheia meta care stochează ordinea
'orderby' => 'meta_value_num' // Sortează după valoarea numerică a meta-cheii
]);
În caz că ajută pe cineva, WordPress stochează o valoare în tabelul termmeta sub cheia 'order' care reprezintă poziția de afișare în meniurile de administrare. Evident, ar trebui adaptată dacă doriți să interogați și alte meta date în același timp.

În loc de menu_order
încearcă term_order
.
Conform documentației din Codex, wp_get_object_terms
acceptă:
- name
- count
- slug
- term_group
- term_order și
- term_id

@izharbuen Te rog să accepți acest răspuns făcând clic pe bifa de lângă el. Mulțumesc :-)

@PieterGoosen izharbuen a spus că nu funcționează, așa că ar fi nepotrivit să marchezi acest lucru ca răspuns corect. Pot confirma că setarea orderby
la term_order
nu funcționează. Mă chinui să înțeleg de ce.

Problema este că wp_term_query
nu acceptă term_order
ca unul dintre parametrii orderby
, iar acest lucru este făcut intenționat. Pur și simplu nu va funcționa din design. De ce? WP face unele lucruri prost uneori, făcându-mă să-mi doresc să dezvolt pentru o altă platformă.

term_order
nu este o ordonare a termenilor într-o taxonomie. Este o ordonare a termenilor în cadrul unui obiect (post).
https://developer.wordpress.org/reference/classes/wp_term_query/__construct/ menționează:
Cu excepția cazului în care $object_ids nu este gol, 'term_order' este tratat la fel ca 'term_id'.
Pentru cei care încearcă să ordoneze termenii pentru un obiect după term_id
, trebuie să furnizați object_ids în interogare.
Pentru toți ceilalți care pun această întrebare și doresc să ordoneze o listă de termeni, nu folosiți term_id
. În schimb, adăugați o valoare meta pentru termen și ordonați după aceasta.
get_terms([
'taxonomy' => 'my_taxonomy',
'meta_key' => 'order',
'orderby' => 'meta_value_num'
]);

wp_term_query
nu acceptă term_order
ca unul dintre parametrii pentru ordonare. Prin urmare, trebuie să adăugați manual această opțiune la variabila de interogare a termenilor, inserând următoarele fragmente în fișierul 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 );
După adăugarea fragmentelor de mai sus, dacă executați un cod similar cu cel de mai jos, veți obține termenii ordonați după term_order.
$terms = get_terms('category', array(
'orderby' => 'term_order',
'order' => 'ASC'
));
A doua abordare, dacă doriți să obțineți termenii ordonați după term_order global și în întreg WordPress, adăugați următoarele fragmente în functions.php.
function uc_get_terms_orderby($orderby, $args){
return 't.term_order';
}
add_filter('get_terms_orderby', 'uc_get_terms_orderby', 10, 2);

Mulți ani mai târziu,
Puteți adăuga acest cod în fișierul 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 );
Acest cod forțează WordPress să utilizeze argumentul orderby => term_order în interogarea termenilor.

Aceasta este o idee
Dar am realizat-o gândindu-mă la ordonarea unei liste în front-end
Trebuie să modifici tabelul "{prefix}term_taxonomy", creând câmpul "term_order". Vezi funcția O_term_update_db():
În functions.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');
?>
Această funcție se referă la baza de date:
În 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;
}
?>
Această funcție este folosită pentru a actualiza tabelul prin Ajax:
În functions.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'=> 'EROARE: '.$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 este necesar http://api.jqueryui.com/sortable/
//Apel "wp_enqueue_script('jquery-ui-sortable');" în 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){
//mesaj de succes aici
alert('Finalizat');
}else{
//mesaj de eroare aici
alert('Ceva nu a funcționat');
}
},
error: function(errorThrown) {
console.log(data);
}
});
});
})(jQuery);
În lista din front-end încearcă asta:
<?php
$terms = O_taxonomy_filter_by_order('taxonomia_ta');
?>
<button type="button" class="btn btn-primary" id="btn-reorder-terms">Salvează</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>
