Skip to content

Instantly share code, notes, and snippets.

@khromov
Last active April 13, 2023 17:36
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save khromov/48218f5ce35cbb6b2e65 to your computer and use it in GitHub Desktop.
Save khromov/48218f5ce35cbb6b2e65 to your computer and use it in GitHub Desktop.
Count post view counts in WordPress via AJAX (Compatible with caching plugins)
<?php
/*
Plugin Name: Simple Popular Posts Lite
Plugin URI: -
Description: -
Version: 2015.03.01
Author: khromov
Author URI: http://snippets.khromov.se
License: GPL2
*/
/**
* Class Simple_Popular_Posts
*/
class Simple_Popular_Posts
{
public static $td = 'spp';
public static $post_types = array('post'); //,'page'
/**
* Constructor sets up all our hooks
*/
function __construct()
{
add_action('wp_footer', array(&$this, 'footer_script'), 999);
add_filter('query_vars', array(&$this, 'query_vars'));
add_action('wp', array(&$this, 'count'));
}
/**
* Adds counting code to footer
*/
function footer_script()
{
if((is_single() || is_attachment() || is_page() || is_singular()) && in_array(get_post_type(get_the_ID()), $this::$post_types)) :
?>
<script async type="text/javascript">
function SimplePopularPosts_AddCount(id, endpoint)
{
var xmlhttp;
var params = "/?spp_count=1&spp_post_id=" + id + "&cachebuster=" + Math.floor((Math.random() * 100000));
if (window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
//alert(xmlhttp.responseText);
}
};
xmlhttp.open("GET", endpoint + params, true);
xmlhttp.send();
}
SimplePopularPosts_AddCount(<?php echo get_the_ID(); ?>, '<?php echo get_site_url(); ?>');
</script>
<?php
endif;
}
/**
* Adds our special query var
*/
function query_vars($query_vars)
{
$query_vars[] = 'spp_count';
$query_vars[] = 'spp_post_id';
return $query_vars;
}
/**
* Count function
*
* TODO: This should be doable with SHORTINIT and would be much faster
*/
function count()
{
/**
* Endpoint for counting visits
*/
if(intval(get_query_var('spp_count')) === 1 && intval(get_query_var('spp_post_id')) !== 0)
{
//JSON response
header('Content-Type: application/json');
$id = intval(get_query_var('spp_post_id'));
$current_count = get_post_meta($id, '_spp_count', true);
if($current_count === '')
$count = 1;
else
$count = intval($current_count)+1;
//Update post meta
update_post_meta($id, '_spp_count', $count);
echo json_encode(array('status' => 'OK', 'visits' => intval($current_count)+1));
}
}
}
$simple_popular_posts = new Simple_Popular_Posts();
@jemoreto
Copy link

Thanks for this!! Working like a charm. Didn't yet tested with cache, but so far, so good. Cheers

@yamahayeuhonda
Copy link

Thanks for this!! Working like a charm. Didn't yet tested with cache, but so far, so good. Cheers

I copy that code and make a plugin, upload and active successful, but have nothing change in my wordpress blog.

Can you help me how to show Views count in post, please.

@khromov
Copy link
Author

khromov commented Sep 15, 2020

@yamahayeuhonda
This snippet contains no user interface. You have to pick up the _spp_count meta key yourself and print it where you want.

I suggest you use this later version of the plugin instead, that shows view counts when you visit a post or through shortcode:
https://github.com/khromov/wp-simple-popular-posts

You can also use Koko Analytics which is also self-hosted and has nice graphs and other features:
https://wordpress.org/plugins/koko-analytics/

@daro2013
Copy link

Dear Developer,

Can you please advise if the above codes still working?

and how to implement it into a wordpress site?

I would like to place a post view counter inside a single page on my wordpress which work with Cache plugins. I have not found one plugin which can do that.

Your help will be very appreciated.

Cheers
Daro

@khromov
Copy link
Author

khromov commented Sep 28, 2020

@daro2013

It should work. To use it in your theme you need to use the following frontend code on your single-post.php / single.php / etc template:

<?php echo (int)get_post_meta(get_the_ID(), '_spp_count', true); ?>

Or if you're happy prepending it to each post using functions.php, something like:

add_filter('the_content', function($content) {
    $prepend = "<span>" . get_post_meta(get_the_ID(), '_spp_count', true) . "</span>"
    return $prepend . $content;
});

@daro2013
Copy link

Hi sir,

It does not work. It only show 0 views.

@khromov
Copy link
Author

khromov commented Sep 29, 2020

@daro2013

I suggest you perform basic troubleshooting (javascript errors, response from Ajax call, etc.)

If you can't make it work, try a plugin like Koko Analytics.

@murugeasamgr
Copy link

cool guys.. just replace line number 37 from<script type="text/javascript"> to <script async type="text/javascript">. it is working on my site.

@khromov
Copy link
Author

khromov commented Apr 13, 2023

@murugeasamgr Thanks, I updated the gist. It's really old, it could be rewritten to use fetch as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment