J.me

Sort by latest post for wp_list_categories

One of my developer friend asked me if we could sort by last post using wp_list_categories function for WordPress. By default, wp_list_categories accept arguments for order by ID, name, slug, count or term_group. Order by latest post is not possible by default, but with a little of tweak using filter hook, we can. 🙂

First, we’ll looking at the function wp_list_categories. This function made call to get_categories to get the list of categories, which made another call to get_terms. Categories in WordPress is basically terms with category taxonomy. Finally, looking on the get_terms function, we will find some delicious filter hook that suitable for our customization.

To be able to change the order, we will have to find a way to manipulate the SQL query and add our magic. Finally, we found the filter hook to add the magic, terms_clauses. The code to call the apply filter is as below:

1
2
$pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' );
$clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args );

As you can see, the $pieces hold a separate pieces of the SQL query. We can add our own query to this separate pieces to form a query for our need. The code we used is as follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function filter_term_sort_by_latest_post_clauses( $pieces, $taxonomies, $args )
{
    global $wpdb;
    if ( in_array('category', $taxonomies) && $args['orderby'] == 'latest_post' )
    {
        $pieces['fields'] .= ", MAX(p.post_date) AS last_date";
        $pieces['join'] .= " JOIN $wpdb->term_relationships AS tr JOIN $wpdb->posts AS p ON p.ID=tr.object_id AND tr.term_taxonomy_id=tt.term_taxonomy_id";
        $pieces['where'] .= " GROUP BY t.term_id";
        $pieces['orderby'] = "ORDER BY last_date";
        $pieces['order'] = "DESC"; // DESC or ASC
    }
    return $pieces;
}
add_filter('terms_clauses', 'filter_term_sort_by_latest_post_clauses', 10, 3);

Add this to functions.php or on your own plugin code, or where ever you wanted, it just needed to be placed before any call of wp_list_categories. Note that we only add this filter if the taxonomy is category, and if the orderby argument is set to latest_post. So our call to wp_list_categories is now:

1
wp_list_categories(array('orderby' => 'latest_post'))

Now your wp_list_categories call will have option to sort by latest post. 🙂

Hope it’s useful for you. Comments is appreciated. 😀

7 comments | Leave a comment

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.