Ordenar get_terms usando un Campo Personalizado
Tengo una taxonomía personalizada "crb_issues" que tiene un campo personalizado asociado llamado "issue_date" que genera un valor de fecha para cada término con el formato "20140601" (añomesdía).
Estoy tratando de mostrar todos los términos de la Taxonomía usando get_terms y ordenarlos por ese campo personalizado. A continuación está el código en el que he estado trabajando, que muestra correctamente el Nombre de los Términos y el valor de "issue_date". Sin embargo, estoy teniendo dificultades para conseguir que lo que se muestra se ordene por ese campo personalizado.
$args = array(
'meta_key' => 'issue_date',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'hide_empty' => true,
'number' => '4',
'fields' => 'all',
);
$terms = get_terms("crb_issues", $args);
if ( !empty( $terms ) && !is_wp_error( $terms ) ){
echo "<ul>";
foreach ( $terms as $term ) {
echo "<li>" . $term->name . "</li>";
the_field('issue_date', $term);
}
echo "</ul>";
}
Cualquier ayuda sería muy apreciada.

En lugar de mostrar tus términos en ese bucle inicial, lo usaría para construir un nuevo array, usando tu issue_date como clave:
$my_new_array = array( );
foreach ( $terms as $term ) {
$issue_date = get_field( 'issue_date', $term );
$my_new_array[$issue_date] = $term->name;
}
Luego puedes recorrer este nuevo array en orden:
ksort( $my_new_array, SORT_NUMERIC );
foreach ( $my_new_array as $issue_date => $term_name ) {
echo "<li>" . $term_name . " " . $issue_date . "</li>";
}
Este código no ha sido probado.

Me gusta la idea, desafortunadamente no soy lo suficientemente inteligente para hacer que funcione correctamente, esto definitivamente muestra todos los términos y demás, pero no en orden de issue_date.

Prueba con la versión modificada anterior. Puede que tengas que forzar el nuevo array al orden correcto.

¡Eso es exactamente lo que estaba buscando en Google cuando vi que publicaste eso! Ja. Lo hice funcionar con una pequeña modificación para que funcione como lo necesito y publicaré mi código.

Buena observación... es extraño que get_terms() tenga orderby meta_value_num... pero no logré que funcionara

Utilicé un método similar, pero quería almacenar más valores de la taxonomía además del nombre y el valor del campo personalizado que proporcioné, así que terminé almacenándolo como un object
y creando un array
muy similar a lo que realmente devuelve la función get_terms
.
Obtén tus términos:
$terms = get_terms('tu-taxonomia');
Luego crea un nuevo array, almacenándolos por el valor de mi campo personalizado, que en este caso era numérico:
$newterms = array();
foreach($terms as $term) {
$order = get_field('order', $term); //ESTE ES EL VALOR DE MI CAMPO PERSONALIZADO
$newterms[$order] = (object) array(
'name' => $term->name,
'slug' => $term->slug,
'term_id' => $term->term_id
);
}
Ordénalos numéricamente:
ksort( $newterms, SORT_NUMERIC );
Luego usa el bucle foreach
para obtener los valores de cada objeto:
foreach ( $newterms as $newterm ) {
echo '<a href="#' . $newterm->slug . '">' . $newterm->name . '</a>';
}
Básicamente, estoy reescribiendo el array para usar la clave de mi orden personalizado, pero en este caso necesitaba el slug, el nombre y el ID del término, así que lo almacené como un objeto en lugar del método anterior.
Mi objetivo final era configurar un Advanced Custom Field para que cuando se creara un término de taxonomía, el usuario pudiera asignarle un orden numérico y luego yo pudiera iterar a través de los términos según el orden deseado.
¡Espero que esto ayude a alguien!

¡Gracias Vancoder por tu ayuda!!! Me he estado arrancando los pelos todo el día intentando resolverlo. Curiosamente, tu solución era una de las seis que tenía escritas en mi pizarra, PERO no tenía ni idea de cómo crear un array usando eso como clave. Soy un novato en eso. A continuación está el código que terminé usando con algunos comentarios para cualquiera que intente hacer esto.
<?php
$terms = get_terms("crb_issues");
$issue_archive = array( ); // crea un array para todos los términos dentro de la taxonomía crb_issues usando el campo personalizado "issue_date" como clave
foreach ( $terms as $term ) {
$issue_date = get_field( 'issue_date', $term );
$issue_archive[$issue_date] = $term->name;
}
krsort( $issue_archive, SORT_NUMERIC ); //ordena el array issue_archive de mayor a menor
foreach ( $issue_archive as $issue_date => $term_name ) {
echo "<li>" . $term_name . " " . $issue_date . "</li>"; //muestra el nombre del término y el campo personalizado issue_date
if (++$i == 4) break; //Detiene el foreach después de 4 elementos
}
?>
Si alguien tiene mejores comentarios para este código, házmelo saber, o mejores formas de manejar cualquier cosa. Pero creo que esta es una solución bastante increíble.

Gracias Phil Hoyt, esto era exactamente lo que estaba buscando. Pero, por desgracia, no pude hacerlo funcionar con mi configuración. Lo que sí funciona es lo siguiente:
<?php
// Solución para ordenar por campo personalizado ACF para categorías de tracks
// http://support.advancedcustomfields.com/forums/topic/sorting-categories-list-by-custom-field/
$categories = get_categories('taxonomy=tracks');
$sorted_cats = array();
foreach($categories as $cat){
//$ordr = get_field('track_order', 'tracks_'.$cat>term_id); //no funcionaba, así que usé la línea de abajo
$ordr = get_field( 'track_order', $cat );
$sorted_cats[$ordr] = $cat;
}
krsort($sorted_cats);//ksort ordena ascendente, krsort invierte el orden (es decir, de mayor a menor)
?>
Saludos

Ordenar términos por el valor 'order' del array en lugar de por la clave del array. Si tienes 2 elementos con la misma clave, el último sobrescribirá al primero. Esto evitará ese problema y hará que todos sean visibles:
$sorted = array();
$args = array( 'hide_empty' => false );
$terms = get_terms( 'my-tax', $args );
if( $terms ) :
foreach ( $terms as $term ) {
$sorted[] = array(
'order' => get_field( 'order', $term ), // Obtener campo de ACF
'name' => $term->name,
);
}
function sortByOrder($a, $b) {
return $a['order'] - $b['order'];
}
usort($sorted, 'sortByOrder');
foreach( $sorted as $t ) :?>
<span>
<?php echo $t['name']; ?>
</span>
<?php endforeach;
endif;
