Wordpress: read counter

Hey guys,
We have set up all possible caching including optimization for WP and cache on edge nodes. But when we enabled the latest we faced the issue that counters of how many people read it are much lower than our analytics. We think that a static copy of the site that is created does not have any scripts that can increment this counter. Do you guys know what would be the fix for this? We are happy with static pages generated otherwise as they give great performance in google insights.

This is a problem I’m struggling with too. Never found a solution besides getting the data from the Google Analytics API.

From my experience where I run W3 Total Cache with Page Cache (and all the other caches) + Cache Level: Cache Everything.

But, in terms of a counter, I have “most read” section which does work with the count (article veiw / refresh page) via Ajax.

That way I get really good performance + I still get the views counted so I could display “most read in past 7 days” news :wink:

Not the best possible solution, but with page cache + cache everything, works like a charm as far for now.

Otherwise, I was thinking to re-write it and experiment a bit and do something with Cloudflare Workers, so I could get less “query jobs” to-do on the database itself when I get a lot of visitors per day (~20k or more), where the MySQL has to do a lot of “update/alter” queries (as my counter works as +1 for a pageview of an article)

Otherwise, I could save the “pageviews” in some log file and gather that from my server, rather than do the MySQL work.

Was thinking about it, but never implemented.

If interested to test out, but could be out of scope for this forums, sharing code here:

// put below code into functions.php
<?php
// AJAX pageview
function citanje() {
    $post_id = $_POST['clanak'];
    if(is_numeric($post_id)){
        $count_key = 'post_views_count';
        $count = get_post_meta($post_id, $count_key, true);
        if($count == ''){
            add_post_meta($post_id, $count_key, '0');
        }else{
            $count = $count + 1;
            update_post_meta($post_id, $count_key, $count);
        }
        die($count);
    }
    else{
        exit;
    }
}
add_action('wp_ajax_nopriv_citanje', 'citanje');
add_action('wp_ajax_citanje', 'citanje');
?>

// put below code into footer.php
<script data-cfasync="false" type="text/javascript">
jQuery(document).ready(function(){
    jQuery.ajax({
        type:"POST",
        url:"https://www.mysite.com/wp-admin/admin-ajax.php", // change to your domain name
        data:{
            action:"citanje",
            clanak:<?php echo $post->ID;?>},
            success:
                function(response){
                    // to-do, or rather not?
                },
            error:
                function(error){
                    // to-do, or rather not?
                }
        });
});
</script>

// put below code into some page to display most read posts in last 7 days
<?php
add_filter('posts_where', 'filter_where_one_week');
$most_view_posts_7_days = new WP_Query(
    array(
        'posts_per_page' => 3,
        'meta_key' => 'post_views_count',
        'orderby'=>'meta_value_num',
        'cat'=> -1,
        'category__not_in' => array(1),
        'post_type'=> 'post',
        'ignore_sticky_posts'=>1,
        'no_found_rows' => true,
        'post_status' => 'publish',
        'cache_results' => false,
        'update_post_term_cache' => false,
        'update_post_meta_cache' => false
    )
);
if ($most_view_posts_7_days->have_posts()) : while ($most_view_posts_7_days->have_posts()) :  $most_view_posts_7_days->the_post();?>
<!-- the post data here -->
<?php endwhile; endif; wp_reset_query(); remove_filter('posts_where', 'filter_where_one_week'); ?>

// put below code into a php file for WP admin dashboard showing "views" column, or put in functions.php
<?php if(is_admin()):
add_action('admin_head','custom_admin_styling');
function custom_admin_styling() {
    echo '<style type="text/css">th#post_views{width:70px;text-align:center;}td.post_views{text-align:center;}</style>';
}

function get_PostViews($post_ID){
    $count_key = 'post_views_count';
    $count = get_post_meta($post_ID,$count_key,true);

    return $count;
}

function post_column_views($newcolumn){
    $newcolumn['post_views'] = __('Views');
    return $newcolumn;
}

function post_custom_column_views($column_name,$id){
    if($column_name === 'post_views'){
        echo get_PostViews(get_the_ID());
    }
}

add_filter('manage_posts_columns','post_column_views');
add_action('manage_posts_custom_column','post_custom_column_views',10,2);
<?php endif;?>

To display count on public post/article, just call the <?php echo get_PostViews(get_the_ID());?>, but again you might need to use Ajax to GET the value of the “read counter” for the article in a real-time as far as if you use above PHP code placed into the single.php file, and the article is cached as a “static HTML” page, the counter wouldn’t update so soon (the number may not be changed as far as it would be cached at the time when the post/article is being cached/generated).

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.