Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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;
}
@jayarnielsen

This comment has been minimized.

Copy link
Owner Author

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Jun 3, 2015

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

@Monkeytown64

This comment has been minimized.

Copy link

commented Jul 1, 2015

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

This comment has been minimized.

Copy link

commented Aug 5, 2015

Works like a champ, thanks!

@pablo-sg-pacheco

This comment has been minimized.

Copy link

commented Mar 22, 2016

Thank you

@auz1111

This comment has been minimized.

Copy link

commented Apr 6, 2017

This saved my life! ;) Thank you!

@johngilesyoder

This comment has been minimized.

Copy link

commented Jun 23, 2017

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

@jurv

This comment has been minimized.

Copy link

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 !

@prefacestudios

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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
You can’t perform that action at this time.