Of course, Jetpack is meant to be a “one size fits all” approach to WordPress; its engineers have designed Jetpack to be as simple as possible for people to start using, but often professional sites need professionally-customized features. Fortunately, Jetpack’s source is pretty-well documented, and we’re able to build on top of existing functionality.

Today, we’re going to use Jetpack’s stats_get_csv() function — normally used to populate the “Top Posts” widget — to create a WP_Query object that we can use like we would any other.

Why would I want my popular posts in a WP_Query object?

There are plenty of cases where you may want to highlight the content that’s currently popular on your site. A perfect example is the Growella homepage: as of this week, all of the homepage content is driven by what’s most popular/trending:

While Jetpack gives you a “Top Posts” widget, the amount of work to twist that widget into the Growella homepage would be enormous. Instead, we can leverage the same functionality the widget is using to query WordPress.com (via Jetpack) about our most popular content.

That function uses the little-known (but awesome)wp_list_pluck() function to collect the “post_id” value for each nested array in $popular_posts, which are then used to populate the post__in argument for WP_Query. Notice that we’re also defining the orderby and order arguments, which ensure that the most popular post is displayed first in the results.

Note: Be careful if you implement this pattern in your site, as you’d be making a new request to WordPress.com every time to run the query. Instead, pick a reasonable amount of time and cache the results (a few hours should suffice for most sites) before trying to get popular post IDs again.

The less-easy way: custom ordering of query results

In previous versions of the Growella homepage, the “easy way” worked perfectly: we were able to build a WP_Query object of our most popular posts for the “More popular articles” section, and if there were no popular posts for whatever reason we could simply hide the section.

While working on our staging site, however, it occurred to me that we would face a problem: new content is regularly being added to Growella.com, but the staging site is falling more and more out-of-sync with each passing day. It’s not unreasonable to assume that there will come a day when none of the most popular posts (according to Jetpack) existing in our staging environment, which means our post__in query argument would result in an empty result set.

This forced us to rethink how we approached popular posts: we want the most popular posts to be pushed to the front of “Now Trending”, but if we don’t have valid post IDs we still want something to appear. We were able to accomplish this by not using the post__in argument and instead writing a custom posts_orderby callback:

Understanding the SQL

FIELD() returns the index position of the searching string from a list of strings. If the search string is not found, it returns a 0 (zero). If the search string is NULL, the return value is 0 because NULL fails equality comparison with any value. —w3resource.com

For a frame of reference, the SQL statement for a standard WP_Query instance looks something like this:

What’s great about this approach is that if, for whatever reason, one or more of the popular posts ID isn’t in the result set then the database will simply ignore it and instead include what would have been the 11th post at the end of the result set.