I looked around again with a more relaxed mind and figured out that the_posts
is the action hook I was looking for. This is how I just did it:
add_action(
'the_post',
function ( $post ) {
$count = (int) get_field('views');
$count++;
update_field('views', $count);
}
);
Now I’ll just figure out how to sort it by an ACF field…
Update: Nope, this will not work, because the_post
runs 10 times in the main query /news/
for each of the 10 items, so even getting the index would increase the view counts. Back to the drawing board…
Update 2: My final idea is to still use the the_post
hook as used above, but by adding a ?index=true
parameter, which will only be specified with the /news/
endpoint, eg. /news?index=true
. I’ll then update the hook function to only count a view if there is no index
query string parameter set. Finally, I will hook into the main WP_Query and sort the items by the count before they’re sent out. If this doesn’t work, I’m trashing this whole directory and building the app from scratch using Laravel.
Update 3: I think the last idea is probably not the cleanest or the correct way to do this. I ended up adding a custom endpoint only for counting views, accepting that this is a custom functionality requirement. I did it like this:
function aalaap_count_view( $data ) {
$post = get_post( $data['id'] );
if ( empty( $post ) ) {
return new WP_Error( 'aalaap_post_not_found', 'Invalid post', array( 'status' => 404 ) );
}
// Now update the ACF field (or whatever you wish)
$count = (int) get_field('views', $post->ID);
$count++;
update_field('views', $count, $post->ID);
return new WP_REST_Response($count);
}
add_action( 'rest_api_init', function () {
register_rest_route( 'aalaap/v1', '/countview/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'aalaap_count_view',
) );
} );
Thanks to @Mark-Kaplun for the suggestion in the other answer.