get_terms orderby name as numbers

I have a custom taxonomy filled with terms such as ‘volume 1’, ‘volume 2’, ‘issue 1’, ‘issue 2’, ‘issue 10’ and get_terms orderby name returns list as:
issue 1, issue 10, issue 2 though I need it to be issue 1, issue 2, issue 10

I tried searching wp.stackexchange and using my google-fu to no avail. Any help would be greatly appreciated.

Related posts

Leave a Reply

4 comments

  1. I know this post is very old but still answering for others who reach here.

    Following is a very simple filter to sort the terms as numbers. You only need to set the variable $taxonomy_to_sort with taxonomy slug and place it in functions.php of your theme.

    add_filter( 'get_terms_orderby', 'terms_order_as_number', 10,  3);
    
    function terms_order_as_number($order_by, $args, $taxonomies){
    
        $taxonomy_to_sort = "numbers";
    
        if(in_array($taxonomy_to_sort, $taxonomies)){
            $order_by .=  " * 1";
        }
    
        return $order_by;
    }
    
  2. There are many similar posts on the forum, if you look around.

    You do not have numbers. Therefore you cannot sort numerically. You have to sort alphabetically and that will give you the pattern you see. I am honestly not even sure if get_terms supports a numeric sort (at a glance I’d say it doesn’t) since I doubt many terms are entirely made up of numbers .

    You have a couple of options.

    1. Write you own SQL query. I think, but I am not sure, you can do this
      in pure SQL but it would be tricky– you’d have to substr the
      term name and sort on that. It would be hairy and probably not very efficient.
    2. If you are pulling a few terms at a time, you could sort them in PHP
      before you display them. You’d have to do the same thing as in the
      SQL and substr the name, sort, and put it back together. Any pagination would be problematic with this approach.
  3. Where’s that problems root?

    First, you’re asking to sort by a part that is inside some string. This is no native functionality in any programming language.

    Second, your actual problem is not “sorting by number”, but the way you constructed those numbers. If you’d have known this issue in front (and taken it into account), you could’ve written a filter that would pad those zeros in front of your numbers.

    How to ignore the actual problem and work around it.

    This doesn’t really fix the problem, but as we (and maybe you too) don’t know how many “issues” you might come up with (10, 1k, 100k?), we’re just adding the sorting when displaying it. Here’s a template tag for you to use:

    function wpse80063_numsorted_issues()
    {
        $terms  = get_terms( 'issues', array( /* of possible args */ );
        $digits = strlen( count( $terms ) );
        $sorted_terms = array();
        foreach ( $terms as $term )
        {
            preg_match( "/d+/", $term, $nr );
            $nr = sprintf( "%0{digits}d", $nr );
            // If the above line doesn't work, take this one:
            // $nr = str_pad( $nr, $digits, "0", STR_PAD_LEFT );
            $sorted_terms[ $nr ] = $term;
        }
        ! empty( $sorted_terms ) AND sort( $sorted_terms );
    
        return $sorted_terms;
    }
    
  4. I struggled to get this to work,

    With a great help from https://objectiv.co/taking-natural-sort-alphanumeric-wordpress-even/

    add_filter('get_terms', 'sort_terms_naturally', 20, 3);
    
    function sort_terms_naturally ( $terms, $taxonomies, $args ) {
        $taxonomy_to_sort = "pa_size";
        if(in_array($taxonomy_to_sort, $taxonomies) && count($taxonomies) == 1 ){ // just sort natuarly the terms in the sidebar
            $sort_terms = array();
    
            foreach($terms as $term) {
                $sort_terms[$term->name] = $term;
            }
    
            uksort( $sort_terms, 'strnatcmp');
    
            if ( strtolower($args['order']) == "desc" || true) $sort_terms = array_reverse($sort_terms);
    
            return $sort_terms;
        }
        return $terms;
    }