Ordonează get_terms folosind un câmp personalizat

12 sept. 2014, 19:57:44
Vizualizări: 29.8K
Voturi: 7

Am o taxonomie personalizată "crb_issues" care are asociat un câmp personalizat "issue_date" ce returnează o valoare de tip dată pentru fiecare termen în formatul "20140601" (an-lună-zi).

Încerc să afișez toți termenii taxonomiei folosind get_terms și să îi ordonez după acel câmp personalizat. Mai jos este codul la care lucrez, care afișează corect numele termenilor și valoarea câmpului "issue_date", dar am dificultăți în a ordona rezultatele după acest câmp personalizat.

$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>";
 }

Orice ajutor ar fi foarte apreciat.

2
Comentarii

Notă: Am găsit soluții prin plugin-uri, cum ar fi Advanced Taxonomy Terms Order, care îmi permite să le aranjez prin drag and drop în ordinea corectă. Dar aș prefera să rezolv asta prin orderby sau într-un mod de sortare automată.

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

Poți consulta următorul thread: http://wordpress.stackexchange.com/questions/117147/order-get-terms-by-custom-field

Sau acest link: http://www.wphub.com/sorting-categories-custom-sort-order/

Sper că te ajută.

Domain Domain
12 sept. 2014 21:00:22
Toate răspunsurile la întrebare 6
1
10

O soluție mult mai scurtă, adaugă asta înainte de foreach:

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

Cea mai bună deoarece nu contează dacă valorile de sortare sunt identice sau nu și este cea mai elegantă soluție.

Picard Picard
30 nov. 2021 01:31:11
5

În loc să afișezi termenii în acea buclă inițială, aș folosi-o pentru a construi un nou array, cu issue_date ca cheie:

$my_new_array = array( );
foreach ( $terms as $term ) {
    $issue_date = get_field( 'issue_date', $term );
    $my_new_array[$issue_date] = $term->name;
}

Apoi poți parcurge acest nou array în ordine:

ksort( $my_new_array, SORT_NUMERIC );

foreach ( $my_new_array as $issue_date => $term_name ) {
   echo "<li>" . $term_name . " " . $issue_date . "</li>";
}

Acest cod nu a fost testat.

12 sept. 2014 21:41:49
Comentarii

Îmi place ideea, din păcate nu sunt suficient de inteligent ca să o fac să funcționeze corect, acest cod afișează cu siguranță toți termenii și altele, dar nu în ordinea issue_date.

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

Încearcă versiunea modificată de mai sus. Poate va trebui să forțezi noul array în ordinea corectă.

vancoder vancoder
12 sept. 2014 22:06:53

Exact la asta căutam pe Google când am văzut postarea ta! Haha. Am reușit să o fac să funcționeze modificând puțin pentru a se potrivi nevoilor mele și voi posta codul meu.

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

Bun punctat... e ciudat că get_terms() are orderby meta_value_num... dar nu am reușit să-l fac să funcționeze

GDY GDY
23 dec. 2016 10:37:21

Atenție, dacă unul sau mai mulți termeni au exact aceeași dată de emitere, se vor suprascrie unul pe altul

uruk uruk
27 apr. 2017 15:28:08
2

Am folosit o metodă similară, dar am dorit să stochez mai multe valori din taxonomie decât numele și valoarea câmpului personalizat pe care le-am furnizat, așa că am ajuns să le stochez ca un obiect și să creez un array similar cu ceea ce este returnat efectiv atunci când utilizați funcția get_terms.

Obțineți termenii:

$terms = get_terms('your-taxonomy');

Apoi creați un nou array, stocându-le după valoarea câmpului meu personalizat, care în acest caz a fost numerică:

$newterms = array(); 
foreach($terms as $term) {
    $order = get_field('order', $term); //ACESTA ESTE VALOAREA CÂMPULUI MEU PERSONALIZAT                
    $newterms[$order] = (object) array(
            'name' => $term->name,
            'slug' => $term->slug,
            'term_id' => $term->term_id
    );
}

Sortați-le numeric:

ksort( $newterms, SORT_NUMERIC );

Apoi utilizați bucla foreach pentru a obține valorile fiecărui obiect:

foreach ( $newterms as $newterm ) {     
        echo '<a href="#' . $newterm->slug . '">' . $newterm->name . '</a>';
}

Deci, în esență, rescriu array-ul pentru a utiliza cheia ordinii mele personalizate, dar în acest caz aveam nevoie de slug, nume și ID-ul termenului, așa că l-am stocat ca un obiect, mai degrabă decât metoda de mai sus.

Scopul meu final a fost să configurez un Advanced Custom Field astfel încât atunci când se creează un termen de taxonomie, acesta să poată primi o ordine numerică de la utilizator, iar apoi să pot parcurge termenii în funcție de ordinea dorită.

Sper că acest lucru ajută pe cineva!

14 oct. 2015 21:22:10
Comentarii

Acesta ar trebui să fie răspunsul acceptat. Bună treabă.

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

Pot lucra cu asta, dar cum a comentat uruk la soluția lui vancoder, dacă 2 sau mai multe elemente au aceeași valoare în câmpul order, acestea se vor suprascrie și doar ultimul va fi afișat.

David Rhoden David Rhoden
9 iul. 2019 00:12:27
0

Mulțumesc Vancoder pentru ajutor!!! Am tot încercat să rezolv problema toată ziua și eram disperat. Culmea e că soluția ta era una dintre cele șase pe care le-am notat pe tablă, DAR nu aveam nicio idee cum să creez efectiv un array folosind-o drept cheie. Sunt începător în astfel de lucruri. Mai jos este codul pe care l-am folosit în final, cu câteva comentarii pentru oricine încearcă să facă același lucru!

<?php
$terms = get_terms("crb_issues");
$issue_archive = array( ); // creează un array pentru toți termenii din taxonomia crb_issues folosind câmpul personalizat "issue_date" drept cheie
foreach ( $terms as $term ) {
    $issue_date = get_field( 'issue_date', $term );
    $issue_archive[$issue_date] = $term->name;
}

krsort( $issue_archive, SORT_NUMERIC ); //sortează array-ul issue_archive în ordine descrescătoare

foreach ( $issue_archive as $issue_date => $term_name ) {
    echo "<li>" . $term_name . " " . $issue_date . "</li>"; //afișează numele termenului și câmpul personalizat issue_date
    if (++$i == 4) break; //Oprește foreach după primele 4 intrări
}
?>

Dacă cineva are sugestii mai bune pentru comentariile din acest cod sau modalități mai eficiente de a gestiona anumite aspecte, vă rog să-mi spuneți. Dar cred că aceasta este o soluție destul de bună.

12 sept. 2014 22:25:59
0

Mulțumesc Phil Hoyt, exact la asta mă gândeam. Dar, din păcate, nu am reușit să funcționeze în configurația mea. Ce a funcționat este următoarea soluție:

    <?php
    // Soluție pentru sortarea după câmp personalizat ACF pentru categoriile 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); //nu funcționa, așa că am folosit linia de mai jos
        $ordr = get_field( 'track_order', $cat );
        $sorted_cats[$ordr] = $cat;
    }
    krsort($sorted_cats);//ksort sortează crescător, krsort inversează ordinea (adică de la mare la mic)
    ?>

Noroc

9 mai 2015 04:30:13
0

Sortează termenii după valoarea 'order' din array în loc de cheia array-ului. Dacă ai 2 elemente cu aceeași cheie, ultimul va înlocui primul. Acest lucru va preveni această situație și îi va face pe toți vizibili:

$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 ), // Obține câmpul din 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