Ordenar get_terms usando un Campo Personalizado

12 sept 2014, 19:57:44
Vistas: 29.8K
Votos: 7

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.

2
Comentarios

Nota: He encontrado soluciones con plugins como Advanced Taxonomy Terms Order, que me permite arrastrar y soltar los términos en el orden correcto, pero preferiría que esto se maneje mediante un orderby o alguna forma de ordenación automática.

Phil Hoyt Phil Hoyt
12 sept 2014 20:45:14

Puedes consultar este hilo: http://wordpress.stackexchange.com/questions/117147/order-get-terms-by-custom-field

O este enlace: http://www.wphub.com/sorting-categories-custom-sort-order/

Espero que te ayude.

Domain Domain
12 sept 2014 21:00:22
Todas las respuestas a la pregunta 6
1
10

Una solución mucho más corta, solo agrega esto antes del foreach:

usort($terms, function($a, $b) {
    return get_field('issue_date', $a) - get_field('issue_date', $b);
});
9 ene 2016 21:23:52
Comentarios

Lo mejor porque no importa si los valores de ordenación son idénticos o no y es la solución más elegante.

Picard Picard
30 nov 2021 01:31:11
5

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.

12 sept 2014 21:41:49
Comentarios

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.

Phil Hoyt Phil Hoyt
12 sept 2014 21:57:06

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

vancoder vancoder
12 sept 2014 22:06:53

¡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.

Phil Hoyt Phil Hoyt
12 sept 2014 22:18:10

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

GDY GDY
23 dic 2016 10:37:21

Tengan en cuenta que si uno o más términos tienen exactamente la misma fecha de publicación, se sobrescribirán entre sí

uruk uruk
27 abr 2017 15:28:08
2

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!

14 oct 2015 21:22:10
Comentarios

Esta debería ser la respuesta aceptada. Buen trabajo.

Christine Cooper Christine Cooper
6 mar 2016 17:34:40

Puedo trabajar con esto, pero como uruk comentó en la solución de vancoder, si 2 o más elementos tienen el mismo valor en el campo order, se sobrescribirán entre sí y solo se mostrará el último.

David Rhoden David Rhoden
9 jul 2019 00:12:27
0

¡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.

12 sept 2014 22:25:59
0

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

9 may 2015 04:30:13
0

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;
12 feb 2016 05:01:01