Find popular posts with the WordPress REST API

Don’t use a plugin if you don’t have to. Especially for something so simple (and fun).

Ben Zumdahl
Nov 10, 2017 · 3 min read

A frequent request we receive from clients is to include a “Most Viewed” or “Trending” posts list. WordPress itself doesn’t count page views and thus doesn’t offer an out-of-the-box method for finding popular posts. So what to do?

While Jetpack and other plugins offer this functionality we aim to limit the use of plugins to those truly essential so as to avoid unnecessary conflicts and performance issues. We want simple, effective solutions. So in this case I built one, and I opted to use the WP REST API to do so.

Since all I needed was a way to count each time a post was viewed, I used register_rest_route() to create a new endpoint. When a GET request is made to this endpoint a callback function is run, which does the following:

  1. Accepts the post ID that was passed as part of the GET request URL

Here’s the actual code (add to functions.php or a plugin) to accomplish this:

add_action( 'rest_api_init', function () {
register_rest_route( 'base', '/views/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'post_view_counter_function',
));
});
function post_view_counter_function( WP_REST_Request $request ) {
$post_id = $request['id'];
if ( FALSE === get_post_status( $post_id ) ) {
return new WP_Error( 'error_no_post', 'Not a post id', array( 'status' => 404 ) );
} else {
$current_views = get_post_meta( $post_id, 'views', true );
$views = $current_views + 1;
update_post_meta( $post_id, 'views', $views );
return $views;
}
}

To make the GET request I added this jQuery snippet in the single post template (this assumes you have added the post ID as a data-attribute on an element with the post-article class):

$( document ).ready(function() {var postid = $( ".post-article" ).attr( "data-postid" );$.get( "https://websiteurl.com/wp-json/base/views/" + postid);
});

That’s all there is to it! The GET request doesn’t need to actually return any data to the requester (though for the sake of testing, the code above returns the current number of views). It’s simply a way to ping the website and tell it to +1 the current post’s views.

Benefits of this approach include:

  1. Unlike a POST request, no authentication is required.

An easy-to-implement, lightweight solution for the win!


Is your website overrun with plugins? Do you need more control over the content you serve to readers? Let us help you build a solution that’s just right for your needs: https://fiatinsight.com/contact

Fiat Insight

Building products with purpose. Since 2010.

Ben Zumdahl

Written by

Lead Developer at Fiat Insight

Fiat Insight

Building products with purpose. Since 2010.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade