Skip to content

Instantly share code, notes, and snippets.

@jnlsn
Last active February 20, 2022 20:28
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save jnlsn/12f3a586900aa6759639 to your computer and use it in GitHub Desktop.
Save jnlsn/12f3a586900aa6759639 to your computer and use it in GitHub Desktop.
WP Query Orderby Taxonomy Term Name
add_filter('posts_clauses', 'posts_clauses_with_tax', 10, 2);
function posts_clauses_with_tax( $clauses, $wp_query ) {
global $wpdb;
//array of sortable taxonomies
$taxonomies = array('example-taxonomy', 'other-taxonomy');
if (isset($wp_query->query['orderby']) && in_array($wp_query->query['orderby'], $taxonomies)) {
$clauses['join'] .= "
LEFT OUTER JOIN {$wpdb->term_relationships} AS rel2 ON {$wpdb->posts}.ID = rel2.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} AS tax2 ON rel2.term_taxonomy_id = tax2.term_taxonomy_id
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
";
$clauses['where'] .= " AND (taxonomy = '{$wp_query->query['orderby']}' OR taxonomy IS NULL)";
$clauses['groupby'] = "rel2.object_id";
$clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
$clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ? 'ASC' : 'DESC';
}
return $clauses;
}
@jnlsn
Copy link
Author

jnlsn commented Apr 2, 2015

The wordpress post query functions have many excellent features built in for selecting and ordering a post query, but the one thing it can't do is order by taxonomy name. For the average user, this is not a big deal, but once you start making complicated relationships with custom post types and taxonomies, it can be critical. Fortunately I stumbled upon this little function that allows sorting by a custom taxonomy name. Unfortunately it didn't play well with anything but the simplest queries and was limited to only one taxonomy. I made a few adjustments to the function to allow sorting by any taxonomy.

Notice that I have defined the sortable taxonomies in an array. If you wanted to be able to sort by anything without having to first define it in this array, you could use the is_tax() function. This function will run every single time posts are queried, so I would caution against using is_tax() as it could potentially slow your site down. While it would be much simpler to eliminate the $taxonomies array and use is_tax($wp_query->query['orderby']) instead of in_array($wp-query->query['orderby'], $taxonomies), I opted for speed over ease of use.

To enable taxonomy term sorting, copy the script into your functions.php file and replace the $taxonomies array with an array of your taxonomy slugs. Then in you post query simply set the orderby parameter to the taxonomy slug you want to sort by.

@pwenzel
Copy link

pwenzel commented May 14, 2015

Found this by chance in a Google search, and it worked exactly as I needed. Thank you so much for sharing.

@adriandmitroca
Copy link

Thank you. It works perfectly and saved me hours of searching.

@Monkeytown64
Copy link

Hi,
Seems to be what I was looking for... but I'm new in php, and don't remember a lot my sql lessons...
What should I change to order posts by child term (hierarchical) instead of main tax ?
Would appreciate a lot your help... ! (please excuse my bad english, french guy here...)

@ndyjones
Copy link

ndyjones commented Aug 5, 2015

Works like a champ, thanks!

@pablo-sg-pacheco
Copy link

Thank you

@auz1111
Copy link

auz1111 commented Apr 6, 2017

This saved my life! ;) Thank you!

@johngilesyoder
Copy link

Kudos. Needed this badly and it works likes a charm.

@jurv
Copy link

jurv commented May 3, 2018

Thank you so much ! I spent hours searching for a solution, some of what I found on the net was really disgusting : aggregation of multiple query results (one by taxonomy term), retrieving all posts to sort them and then apply a pagination in PHP, etc...
This is by far the cleanest solution ! I had to twist it a bit of course, but you saved me a lot of time. Thanks again !

Copy link

ghost commented May 4, 2018

Great, thanks a lot.

In case anyone is trying to order by integer and you want 1,2,3,4 instead of 1,10,11,12 etc replace:

$clauses['orderby'] = "GROUP_CONCAT({$wpdb->;terms}.name ORDER BY name ASC) ";

with

$clauses['orderby'] = "CAST(GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) as DECIMAL) ";

@ianhoyte
Copy link

ianhoyte commented Aug 8, 2019

+1 works great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment