I have this...

<?php echo strip_tags (get_the_term_list( $post->ID, 'school-year-level', ' ',', ')); ?>

which nicely unlinks and comma separates a list of terms from a specified custom taxonomy (school-year-level). However the list isn't in the order I want. I've hunted down this... http://codex.wordpress.org/Function_Reference/wp_get_object_terms

<?php $product_terms = wp_get_object_terms( $post->ID,  'school-year-level', $args );
$args = array('orderby' => 'slug', 'order' => 'ASC', 'fields' => 'all');
if ( ! empty( $product_terms ) ) {
    if ( ! is_wp_error( $product_terms ) ) {
            foreach( $product_terms as $term ) {
                echo '<a href="' . get_term_link( $term->slug, 'school-year-level' ) . '">' . esc_html( $term->name ) . '</a> '; 

but my attempts to 1. make it a comma separated list, and 2. get the orderby $args to work 3. strip_tags it haven't been working for me :(


For the sake of performance, you should rather use get_the_terms() to get the post terms and then use usort to sort the results. wp_get_object_terms() are not cached and therefor requires an extra db call per post queried.

While at it, also, you would want to pass the complete term object to get_term_link(). If the term is not cached, and the slug or ID is passed to get_term_link(), get_term_link() will query the db to get the complete term object, which you already have. Passing the complete term object saves unnecessary db calls or having to look in the term cache for the term object.

Lastly, you should always define $args first before using it. In your original code, you are trying to use $args first, and then define it, this was the main issue for your failure.

Anyways, you can use the following idea to sort your post terms

$product_terms = get_the_terms( get_the_ID(), 'school-year-level' );

// Make sure we have terms and also check for WP_Error object
if (    $product_terms
     && !is_wp_error( $product_terms )
) {
    @usort( $product_terms, function ( $a, $b )
        return strcasecmp( 

    // Display your terms as normal
    $term_list = [];
    foreach ( $product_terms as $term ) 
        $term_list[] = esc_html( $term->name );

    echo implode( ', ', $term_list );


To make clicable links that link back to the term's archive page, you need to replace

$term_list[] = esc_html( $term->name );


$term_list[] = '<a href="' . get_term_link( $term ) . '">' . esc_html( $term->name ) . '</a>';

Note, if you pass the complete term object to get_term_link(), you do not need to pass the taxonomy. The taxonomy is gathered from the term object.

| improve this answer | |
  • How would this be edited to include the terms as "linkable"? – Pete Apr 19 '16 at 12:27
  • See my EDIT ;-) – Pieter Goosen Apr 19 '16 at 12:42
  • Not to split hairs, and while I agree with Pieter's answer in terms of best practices, my answer--the originally accepted--actually answered the question posted. – darrinb Apr 20 '16 at 3:59
  • @darrinb answering a question is not always about fixing the code in OP, if there is a smarter way to do something which the OP can benefit from (or for that matter anyone who finds the post), why not make the OP aware of it. Yes, you've answered the question directly, I just posted a better alternative (which would be more beneficial) to what the OP is currently using. The onus still lies with the OP to accept whatever answer he feels is the better approach to him. ;-) – Pieter Goosen Apr 20 '16 at 6:04

Try this (tested on my dev site):

$taxonomy = 'name-of-your-taxonomy';
$args = array('orderby' => 'slug', 'order' => 'ASC', 'fields' => 'all');
$product_terms = wp_get_object_terms( $post->ID, $taxonomy, $args );

if ( ! empty( $product_terms ) && ! is_wp_error( $product_terms ) ) {
    $terms = array();
    foreach( $product_terms as $term ) {
        $terms[] = esc_html( $term->name );
    echo join( ', ', $terms );
| improve this answer | |
  • Just a note, wp_get_object_terms() results in an extra db call for every post queried, using get_the_terms() with usort() is better proposition here as it is faster and no extra db queries – Pieter Goosen Apr 19 '16 at 4:34
  • Ooooo! How would you do that? @PieterGoosen – Pete Apr 19 '16 at 7:49
  • Just a heads up, get_the_terms() actually calls wp_get_object_terms() if the terms aren't already cached. – darrinb Apr 20 '16 at 4:03
  • Post terms are always cached unless you have set your query explicitely to not cache post terms (update_post_term_cache=false), which would be really stupid. In this case, any term related function would make db calls. You would see the difference in db calls when you have some script running to display the amount of db calls made for a specific piece of code ;-) – Pieter Goosen Apr 20 '16 at 5:57

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.