Jump to content

Page Hit Counter – Simple Page View Tracking


David Karich

Recommended Posts

22 hours ago, loukote said:

Above you mention the ProCache module. Do I understand correctly that the counting will work correctly even with the standard PW template cache mechanism?

Hi @loukote, yes that's right. The tracking and counting of PageViews also works with any form of cache. Because a small Javascript is injected, which tracks the view asnychronously, past the cache, without affecting the cache.

Link to comment
Share on other sites

  • 2 weeks later...

Haven't tested yet, but it seems that it stores only int value of total sum of all time views? So not possible to use for "most viewed pages this week" for example?

Other than that it looks like a perfect module for many use cases!

Link to comment
Share on other sites

12 minutes ago, apeisa said:

Haven't tested yet, but it seems that it stores only int value of total sum of all time views? So not possible to use for "most viewed pages this week" for example?

Other than that it looks like a perfect module for many use cases!

Hello apeisa, 

that's correct. It totals all views. However, you can still display something similar to a function like "most of the week". If the page being tracked has a date field. For example I have a news template with the date field "start_date" and activated tracking. Now you can output the 5 most read news of the last week with the following selector: 

$startDate = strtotime("-1 week");
$endDate = strtotime("now");
$bestNews = $pages->find("template=news, start_date>={$startDate}, start_date<={$endDate}, sort=-phits, start=0, limit=5");

 

  • Like 2
Link to comment
Share on other sites

  • 1 month later...

Just spotted a curiosity in my Jumplinks 404 log...

1512599478_2019-03-1402_33_20.thumb.png.01ebc07a890568a285b5fa060cf43ca8.png

.. and found out it's from here PageHitCounter.min.js.

"use strict";(window.PHC=window.PHC||{}).t=function(){try{var e=document.getElementsByTagName("BODY")[0],t=parseInt(e.getAttribute("data-phc"));if(!isNaN(t)){var n=new XMLHttpRequest;n.open("POST",location.pathname.replace(/\/?$/,'/')+"phcv1",!0),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.send(encodeURI("pid="+t))}}catch(e){}},PHC.t();

 

Did I missed that before or is this not working as intended?

2019-03-14 02_32_58.png

Link to comment
Share on other sites

Found another thing... 

My 404 page has the same template as most of my other pages as it's kind of a page builder.

Trying to reset the page count for that template the 404 page still has it counts while other's dont.

400061712_2019-03-1403_44_51.png.8f4ffc773407fd7939eef86494b002b4.png

Trying to be clever and looking up the ID of that page (27) in order to reset the view count an error message shows up.

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND `data` > 0' at line 1

404599281_2019-03-1403_49_00.png.87a346fef9a3a8f524e7953d4a9101e7.png

Link to comment
Share on other sites

  • 4 weeks later...

Hey @David Karich , just passing by to say that I've sent two small PRs for correcting some typos. Super minor thing, but hope you like it. ?

I'm planning to adapt your code to build another module, a download counter. My use case is where the file is hosted on another server, and its link is managed through a URL field.

Link to comment
Share on other sites

PageHitCounter Version 1.2.4

Thanks to @wbmnfktr for reporting the issues. And thanks to @Sergio for the corrections. Both issues have been fixed in version 1.2.4 and the corrections have been applied. Changelog as always updated in the first post. Explanations of the bugs below.

On 3/14/2019 at 2:51 AM, wbmnfktr said:

Just spotted a curiosity in my Jumplinks 404 log...

1512599478_2019-03-1402_33_20.thumb.png.01ebc07a890568a285b5fa060cf43ca8.png

.. and found out it's from here PageHitCounter.min.js.


"use strict";(window.PHC=window.PHC||{}).t=function(){try{var e=document.getElementsByTagName("BODY")[0],t=parseInt(e.getAttribute("data-phc"));if(!isNaN(t)){var n=new XMLHttpRequest;n.open("POST",location.pathname.replace(/\/?$/,'/')+"phcv1",!0),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.send(encodeURI("pid="+t))}}catch(e){}},PHC.t();

 

Did I missed that before or is this not working as intended?

2019-03-14 02_32_58.png

The functionality has always been and is correct. The module sends the data to a fictitious endpoint of the current page. Then the module hooked in before a 404 is triggered and writes the data. The problem here was that the module "Jumplinks" had a lower priority than PageHitCounter. Therefore the request was logged as 404, because jumplinks were executed earlier. Now fixed, PageHits are not logged as 404, regular 404s will be. 

On 3/14/2019 at 3:49 AM, wbmnfktr said:

Found another thing... 

My 404 page has the same template as most of my other pages as it's kind of a page builder.

Trying to reset the page count for that template the 404 page still has it counts while other's dont.

400061712_2019-03-1403_44_51.png.8f4ffc773407fd7939eef86494b002b4.png

Trying to be clever and looking up the ID of that page (27) in order to reset the view count an error message shows up.


SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND `data` > 0' at line 1

404599281_2019-03-1403_49_00.png.87a346fef9a3a8f524e7953d4a9101e7.png

Here was the problem that system templates or pages are excluded in the normal search, without the selector "include=all". This is now included by default.

On 4/10/2019 at 1:11 AM, Sergio said:

Hey @David Karich , just passing by to say that I've sent two small PRs for correcting some typos. Super minor thing, but hope you like it. ?

I'm planning to adapt your code to build another module, a download counter. My use case is where the file is hosted on another server, and its link is managed through a URL field.

Oh, my gosh, there were a lot of typos in there. So if you have a lot on your mind what you're going to code next, you don't look at the comments. Anyway, many thanks for the corrections!

And by the way, I'd love to. Take the code and build something new out of it! ? 

  • Like 5
Link to comment
Share on other sites

9 minutes ago, lokomotivan said:

It doens't work if you have have "Allow URL Segments" option enabled on the template, at least not in my case. Can this be fixed?

Right, I haven't tested it yet. Can you send me your sample configuration? Or did you just activate the option without defining segments?

Link to comment
Share on other sites

13 minutes ago, David Karich said:

Right, I haven't tested it yet. Can you send me your sample configuration? Or did you just activate the option without defining segments?

No segments defined, "just Allow URL Segments?" option checked. When i uncheck it, it start counting ? 

Edit: Otherwise works great, thank you for this module ?

  • Like 1
Link to comment
Share on other sites

On 4/18/2019 at 10:21 AM, lokomotivan said:

It doens't work if you have have "Allow URL Segments" option enabled on the template, at least not in my case. Can this be fixed?

David, I checked here on my project. The module does increment the counter for a page that has Segments turned on BUT it doesn't increment the counter when you access "page-url/segment", which would be expected, right? 

Link to comment
Share on other sites

11 hours ago, Sergio said:

David, I checked here on my project. The module does increment the counter for a page that has Segments turned on BUT it doesn't increment the counter when you access "page-url/segment", which would be expected, right? 

Yep, i think that should be expected. In my case there was no segment in the url just option enabled. Ill test it again, maybe i missed something.

Link to comment
Share on other sites

Sure, but I should rephrase that, it should increment the counter for the page when accessing one, or more, of its segments. Considering the visitor is a different user or that the cookie expired, of course.

Link to comment
Share on other sites

@lokomotivan @Sergio I have now experimented with many options to solve this problem. However, there is only one way, which covers both behaviors. If you don't want segments to be counted, just enable the option as the behavior is current. But if segments are to be counted as well, the segments MUST be defined in the template configuration. For dynamic segments with RegEx. For this I have inserted a passage in the readme with the link to the PW help. 

There is currently no other option. The problem is that the Page Hit Counter hooked into the PageNotFound process (But I also tried PageRender, etc.). If URL segments are allowed but not defined, a 404 is never triggered from Processwire. This means that the Page Hit Counter cannot be called. For the tracking of segments, so simply define the segments. ? 

I also released an update with version 1.2.5, which improves the behavior when tracking 404 errors. All infos and download as always in the first post.

  • Like 3
Link to comment
Share on other sites

  • 2 months later...

@David Karich Very useful module, works like a charm!

I was just wondering if there could be a way to call the resetPageViews from a template file? I would find it more valuable if there's an option to reset templates' page hit counter from the template itself. That way, we don't have to give access to the module settings for the average user to reset page hits.

I've tried to use it, but it seems that the module itself doesn't have a clue about the modules' methods. If this is something that Processwire doesn't process, someone could point out that for me :D

Thank you!

 

Link to comment
Share on other sites

  • 3 weeks later...
  • 1 month later...

A very nice simple tracker - thank you David.

I have one issue – just realized, that pages with tracking activated are "edited" by each hit by "guest" (field phits) – that's obvious. In combination with the module "changelog" – where I want to list pages last edited only by editors – the "edited by guest" makes it difficult to filter out what my editor colleagues have changed recently.

Maybe it's worth adding an option to set the field->save method to "quiet"? 

Quote

quiet (boolean): Specify true to bypass updating of modified user and time

https://processwire.com/api/ref/pages/save-field/

 

Edited by sz-ligatur
too fast… I realized that the plugin save hits via db direct access… so I rashly jump to the wrong conclusion I guess…
Link to comment
Share on other sites

It was my mistake – I use a download-file template, that forces downloading a pdf. To track this I used $page->save('phits') to update the counter. Obviously this is a page edit… by guest.

if ( $user->isGuest() ) {

		$page->phits += 1;
        $page->of(false);
		//$page->save('phits');
		$page->save('phits', array('quiet' => true));
		$page->of(true);
    }

The added option 'quiet' does the trick… 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...