7

I have a custom taxonomy of "crb_issues" that has a custom field associated with it that is "issue_date" which outputs a date value for each term to looks a lot like "20140601" yearmonthday.

I am trying to out put all the Taxonomies terms using get_terms and order them by that custom field. Below is the code I have been working on which outputs the Terms Name and the value of the "issue_date" just fine. But I am having a hard time getting what is outputting to order by that custom field.

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

Any help would be much appreciated.

2

6 Answers 6

4

Rather than outputting your terms in that initial loop, I would use it instead to build a new array, with your issue_date as the key:

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

You can then loop through this new array in order:

ksort( $my_new_array, SORT_NUMERIC );

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

This is untested.

5
  • I like the idea, unfortunately I am not smart enough to get it working right, this definitely outputs all the terms and what not, not in order of the issue_date though.
    – Phil Hoyt
    Commented Sep 12, 2014 at 18:57
  • Try the modified version above. You may have to force the new array into the correct order
    – vancoder
    Commented Sep 12, 2014 at 19:06
  • That is exactly what I was googling when I saw you post that! Hah. I got it working just modding a tad to work how I need it and will post my code.
    – Phil Hoyt
    Commented Sep 12, 2014 at 19:18
  • Good one ... strange is that get_terms() has orderby meta_value_num ... but i didnt get it running
    – GDY
    Commented Dec 23, 2016 at 8:37
  • 2
    Be aware that if one or more terms have the exact same issue date, the are overwriting each other
    – uruk
    Commented Apr 27, 2017 at 12:28
10

A much shorter solution, just add this before foreach:

usort($terms, function($a, $b) {
    return get_field('issue_date', $a) - get_field('issue_date', $b);
});
1
  • Best because doesn't care if sorting values are identical or not and is the most elegant solution.
    – Picard
    Commented Nov 29, 2021 at 23:31
4

I used a similar method, but I wanted to store more values from the taxonomy than the name and custom field value I gave, so I ended up storing it as an object and creating an array much like what is actually returned when you use the function get_terms.

Get your terms:

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

Then create a new array, storing them by my custom field value, which happened to be numeric in this case:

$newterms = array(); 
foreach($terms as $term) {
    $order = get_field('order', $term); //THIS MY CUSTOM FIELD VALUE                
    $newterms[$order] = (object) array(
            'name' => $term->name,
            'slug' => $term->slug,
            'term_id' => $term->term_id
    );
}

Sort them numerically:

ksort( $newterms, SORT_NUMERIC );

Then use the foreach loop to get the values of each object:

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

So, essentially I am rewriting the array to use the key of my custom order, but in this case I needed the slug, name, and ID of the term, so I stored it as an object, rather than the method above.

My end goal was I set up an Advanced Custom Field so when a taxonomy term was created, it could be given a numerical order from the user, and then I could loop through the terms based on their desired order.

Hope this helps someone!

2
  • 2
    This should be the accepted answer. Good job.
    – Christine Cooper
    Commented Mar 6, 2016 at 15:34
  • I can work with this, but as uruk commented on vancoder's solution, if 2 or more elements have the same value in the order field, they will overwrite each other and only the last one will show. Commented Jul 8, 2019 at 21:12
3

Thanks Vancoder for your help!!! I have been ripping my hair out all day trying to figure it out. Funny enough your solution was one of half a dozen I wrote on my whiteboard, BUT I had no clue how to actually create an array with that as a key. I am a noob like that. Below is the code I ended up using with some comments for anyone else trying to do this!

<?php
$terms = get_terms("crb_issues");
$issue_archive = array( ); // creates an array for all terms inside of crb_issues tax using the custom field "issue_date" as the key
foreach ( $terms as $term ) {
    $issue_date = get_field( 'issue_date', $term );
    $issue_archive[$issue_date] = $term->name;
}

krsort( $issue_archive, SORT_NUMERIC ); //sorts the issue_archive array from high to low

foreach ( $issue_archive as $issue_date => $term_name ) {
    echo "<li>" . $term_name . " " . $issue_date . "</li>"; //displays the term name and customfield issue_date
    if (++$i == 4) break; //Stops the foreach after 4
}
?>

If anyone has better comments for this code please let me know, or better ways to handle anything. But I think this is a pretty awesome solution.

0

Thanks Phil Hoyt, this was exactly what I was looking for. But, alas, I couldn't get it to work with my setup. What does work is the following:

    <?php
    // Solution for sorting by ACF custom-field for tracks categories
    // 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); //wasn't working so used the line below
        $ordr = get_field( 'track_order', $cat );
        $sorted_cats[$ordr] = $cat;
    }
    krsort($sorted_cats);//ksort orders ascending, krsort reverses order (i.e. biggest to smallest)
    ?>

Cheers

0

Sort terms by array value 'order' instead of array key. If you have 2 items with same key, last one will override first one. This will prevent that and make all of them visible:

$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 ), // Get field from 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;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.