DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for I have updated my WordPress REST API to set and return the number of views per post
muncey
muncey

Posted on

I have updated my WordPress REST API to set and return the number of views per post

The next iteration or feature I have implemented in my react theme is a view counter which shows the number of views each one of my posts is getting on my WordPress site. The number of views is a number value that is held against each post on my WordPress site using what is known as post meta. Post meta is a mechanism that WordPress provides that will let you store some additional data with each post and is normally set behind the scenes for you by custom PHP code running in either a theme or a plugin.

In my case I have set up a filter inside my functions.php file to increment a post views value by 1 each time a request is made to retrieve data for a specific post via the Rest API. The Rest API is a handy out of the box feature that WordPress provides that will let you access your pages and posts as a JSON string. You can try this out by appending /wp/v2/posts/ to the end of your site URL. You can read more information about the Rest API by going to this site: https://developer.wordpress.org/rest-api/. With WordPress programming what you often need to do is search and find an appropriate hook.

I was not able to find an exact hook for what I wanted to do which is to be able to run some custom code when a user requests a single post via the WordPress API. There are some hooks available for when a post is processed for sending to the user but these hooks also ran when the list of posts were retrieved which isn’t ideal particularly as I couldn’t find an easy way to distinguish between a single post and a list of posts.

So what I found was there is a hook called rest_request_before_callbacks which as the name suggest runs before further processing of a rest request occurs. The documentation for this hook can be found here: https://developer.wordpress.org/reference/hooks/rest_request_before_callbacks/. I feel that there will be a job for future Phil to use another hook or write a custom post handling class but for now this hook works quite well.

Currently my code for this hook looks like the following:

function my_react_count_views( $response, $handler, WP_REST_Request $request ) {
    $id = $request->get_param('id');
    $route = $request->get_route();
    if ((stristr($route, 'posts') || stristr($route, 'pages')) && isset($id)) {
        $views = get_post_meta($id, 'post_views', true);
        if (!$views) {
            add_post_meta($id, 'post_views', 1);
        } else {
            update_post_meta($id, 'post_views', intval($views) + 1);
        }
    }
    return $response; 
}



add_filter( 'rest_request_before_callbacks', 'my_react_count_views', 10, 3 );

Enter fullscreen mode Exit fullscreen mode

I will walk through the code step by step for you.

The first thing I do is attempt to get the id parameter for the post or page by looking for an id in the page parameters using $request->get_param(β€˜id’);. This of course will not work in the future when I move to permalinks but in the interests of getting the work done I have taken this approach for now. I haven’t looked too far into how to get this working with permalinks rather than id’s but I have a feeling the concept will be the same, I will just replace looking for an id with looking for a permalink. The reason for doing this is that I needed something to distinguish between someone viewing a post on a page and someone viewing a list of posts. In my original version I was finding that the counter was increasing each time I viewed the list.

The next step is to check that the route contains either posts or pages by using the PHP stristr function.

So this means that for pages or posts with an id I want to then check the post meta by using the WordPress get_post_meta function. This function will either return a value or null. If the value is null I use add_post_meta to assign a value of 1 to the post_views and if the value is set (i.e. > 0) then I use update_post_meta to store an incremented by 1 value into my WordPress site.

You can view this working on my personal site, https://munceyweb.com by clicking on a post:

Image description

Image description

The post_views counter is available in the Network tools – Preview tab in Chrome, Edge or Brave. You can see that the post_views is returned as part of the meta element and can then be used inside my theme by the React code to render the counter.

Image description

In a future post I will show how I used this value inside my React WordPress theme to render the view using Javascript.

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.