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.

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.

| improve this answer | |
  • 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 Sep 12 '14 at 18:57
  • Try the modified version above. You may have to force the new array into the correct order – vancoder Sep 12 '14 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 Sep 12 '14 at 19:18
  • Good one ... strange is that get_terms() has orderby meta_value_num ... but i didnt get it running – GDY Dec 23 '16 at 8:37
  • 1
    Be aware that if one or more terms have the exact same issue date, the are overwriting each other – uruk Apr 27 '17 at 12:28
6

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);
});
| improve this answer | |
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!

| improve this answer | |
  • 2
    This should be the accepted answer. Good job. – Christine Cooper Mar 6 '16 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. – David Rhoden Jul 8 '19 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.

| improve this answer | |
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

| improve this answer | |
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;
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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