Jump to content

Page Hit Counter – Simple Page View Tracking


Recommended Posts

David i like your module it works nicely. I have an issue using it in combination with amp pages.

With amp pages we are not allowed to inject any java script code. So I want to exclude my amp pages from getting the pagehitcounter.min.js injected. Is their a way to block this?

For the pages were I want to have the java script I can load it manually.

I know you can set templates from getting tracked and not tracked but my issue is that i don't have separate template for an amp page and the normal page

Link to post
Share on other sites
7 hours ago, erikvanberkum said:

David i like your module it works nicely. I have an issue using it in combination with amp pages.

With amp pages we are not allowed to inject any java script code. So I want to exclude my amp pages from getting the pagehitcounter.min.js injected. Is their a way to block this?

For the pages were I want to have the java script I can load it manually.

I know you can set templates from getting tracked and not tracked but my issue is that i don't have separate template for an amp page and the normal page

Hey Erik, here's a suggestion how you can do it manually, at least for those templates that have an AMP version. But I haven't tested it.

  1. Remove the specific template from the "Templates for automatic tracking" configuration and
  2. Add this specific template in the "Templates for allowed API tracking" configuration
  3. In the non-AMP version of the template, you add the following data atrribute to the body tag, with the ID of the current page which should be tracked. For example: 
    <body data-phc="<?php echo $page->id; ?>">
  4. Now manually add the tracking script for the non-AMP version before the closing body tag. 
    <!-- For debugging use PageHitCounter.js -->
    <script defer src="<?php echo $config->urls->PageHitCounter; ?>PageHitCounter.min.js"></script>

That's it.

Link to post
Share on other sites
  • 1 month later...
  • 2 months later...

Dear David Karich. Thanks a lot for this very nifty module.

However I have one issue on a multilanguage site. I want to count the phits on one template. I configured it in the module settings. For that template some pages work perfectly well. But for some other (same template), I see that the phits was counted on the debug console But it doesn't seem to be recorded in the database ( the phits remain at 0). These pages are not in the same language that those that work. I guess it has to do with the language but I have not yet figured out the use case.

Has anybody else used this module on a multi language site ? Any known issue in this contexte ?

Thanks in advance

Link to post
Share on other sites

@Gideon : tks for your answer. That's not a good news though. The module is realy well done with all the options available in the admin.

@David : any chance that you add support for multilanguage sites in the module's roadmap in the near future.

Thanks

Link to post
Share on other sites

Hello everyone,

I realized that I might have not been precise enough with my question.

I have a multi language web site. I have a template called document. I have 4 language : default (not used on the front end), french and english and spanish

A page with that template can be either active  in french , in english, spanish or active in all of them. English in the not the default language though (it is the first additional language).

My need is to have page hit counts views irrespective of the language. and stores views irrespective of the language. so if a page gets 1 view in english and 1 view in french. It would count 2 views.

I tested my use case with Page hit module. I found that the views were properly recorded if the page was active english. But if the page is active in french or spanish the view is counted in the front end (on the debug consol it says 'Page Hit Counter: Tracked' but doesn't get recorded in the database.

Why would it work for the first language that is not the default language and not with the other one. For the purpose of my test I duplicated the same page so only the language active status was changed. The change of url (from /fr to /en) is not the problem cause the page that has both language get the counts recorded from both the url language.

I guess the module is not working in my use case even if I didn't need the recorded hits to be per se multilanguage.

Link to post
Share on other sites
  • 3 weeks later...
  • 4 months later...

Hey @David Karich thx for this great module 🙂 

Could you please make the buildPageListHitCounter() method public, so that I can use it on my custom pagelist labels? Then I can build more complex labels like this one:


  // hit counter
  $hits = $this->wire->modules->get('PageHitCounter')
    ->buildPageListHitCounter((int) $page->get(PageHitCounter::PHCFIELDNAME));

  $event->return = $hits.$badge($type($page)).$page->range->format().", ".$page->title;

Thx

Link to post
Share on other sites
On 6/29/2020 at 3:11 AM, Krlos said:

Hi, I am seeing the same issue, how did you solve it?

Maybe PHC simply does not track your visits because you are logged in? You can try visiting the page in incognito mode.

Link to post
Share on other sites
On 11/26/2020 at 8:33 PM, bernhard said:

Hey @David Karich thx for this great module 🙂 

Could you please make the buildPageListHitCounter() method public, so that I can use it on my custom pagelist labels? Then I can build more complex labels like this one:



  // hit counter
  $hits = $this->wire->modules->get('PageHitCounter')
    ->buildPageListHitCounter((int) $page->get(PageHitCounter::PHCFIELDNAME));

  $event->return = $hits.$badge($type($page)).$page->range->format().", ".$page->title;

Thx

As requested, in version 1.2.7 the function is now public. 🙂 

  • Thanks 1
Link to post
Share on other sites

Thx David,

hm... reading this portion of code again, I think it would be a lot nicer to have a method on the page object for that:

$event->return = 
	$page->phcLabel()
	.$badge($type($page))
	.$page->range->format()
	.", ".$page->title;

What do you think?

$this->addHookMethod("Page::phcLabel", function($event) {
	$page = $event->object;
	$cnt = (int)$page->get(PageHitCounter::PHCFIELDNAME);
	$event->return = $this->buildPageListHitCounter($cnt);
});

 

Link to post
Share on other sites
4 hours ago, bernhard said:

Thx David,

hm... reading this portion of code again, I think it would be a lot nicer to have a method on the page object for that:


$event->return = 
	$page->phcLabel()
	.$badge($type($page))
	.$page->range->format()
	.", ".$page->title;

What do you think?


$this->addHookMethod("Page::phcLabel", function($event) {
	$page = $event->object;
	$cnt = (int)$page->get(PageHitCounter::PHCFIELDNAME);
	$event->return = $this->buildPageListHitCounter($cnt);
});

 

Honestly, I think that for this particular case, implementing a hook is a bit too much. Since you can easily access the counter value via "$page->phits" at any time, you can modify and build your labels in the PageTree yourself. In the module configurations you can simply specify the templates for which the counter will not be automatically output as a label under "Exclude templates for page tree counter". Or disable it completely if you build all your labels yourself. 🙂 

Or have I missed something? 😄 

Link to post
Share on other sites
On 6/13/2020 at 3:37 PM, antpre said:

Hello everyone,

I realized that I might have not been precise enough with my question.

I have a multi language web site. I have a template called document. I have 4 language : default (not used on the front end), french and english and spanish

A page with that template can be either active  in french , in english, spanish or active in all of them. English in the not the default language though (it is the first additional language).

My need is to have page hit counts views irrespective of the language. and stores views irrespective of the language. so if a page gets 1 view in english and 1 view in french. It would count 2 views.

I tested my use case with Page hit module. I found that the views were properly recorded if the page was active english. But if the page is active in french or spanish the view is counted in the front end (on the debug consol it says 'Page Hit Counter: Tracked' but doesn't get recorded in the database.

Why would it work for the first language that is not the default language and not with the other one. For the purpose of my test I duplicated the same page so only the language active status was changed. The change of url (from /fr to /en) is not the problem cause the page that has both language get the counts recorded from both the url language.

I guess the module is not working in my use case even if I didn't need the recorded hits to be per se multilanguage.

Unfortunately I cannot reproduce an issue here. I have used the module in several productive multilingual environments. No matter from which language version (even for me the default is not english) it is counted. Maybe you have "URL segments" in use? I have written an info about this in the readme. 

A separate counter function for each language version is not planned. All hits are summed up, no matter from which language. Maybe in the future, when I have more time for it. Sorry.

Link to post
Share on other sites
15 hours ago, David Karich said:

Honestly, I think that for this particular case, implementing a hook is a bit too much.

Ok thx, I've refactored a little and that's totally fine, you're right 🙂 

  $phc = $this->wire->modules->get('PageHitCounter');
  $event->return =
    $phc->buildPageListHitCounter($page->phits)
    .$badge($type($page))
    .$page->range->format()
    .", ".$page->title;

 

  • Like 1
Link to post
Share on other sites
  • 2 months later...

Hi, today's 2.0 update killed the backend here on some installs... Reverting to 1.2.7 fixed it:

PDOException #42S22
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_phits.last_hit' in 'field list'

 

Link to post
Share on other sites

@David Karich Not sure, but probably it's more right to use 'return' instead 'exit()' across 'trackPageView' so we still get 404 page. Currently, I'm getting a blank page with 200 code when I directly access any page with prepended 'phcv1' segment with a template that added wether to API or automatic tracking templates list.

Link to post
Share on other sites

Version 2.0.0 as new master version available (PLEASE READ!)

 

New since 2.0.0: Ignore URL segments

If a template has URL segments configured, each hit on a different segment is counted as a new hit. Enable "Ignore URL segments" so that dynamic segments are not counted individually on the base template / page.

New since 2.0.0: Use cookieless tracking (Experimental)

Enable this option to not use individual cookies for tracking or if you have many different pages you want to track. The limit for cookies is 50 per domain for all cookies on the page. If the option is enabled, PHP session storage is used. Downside: you can't set the lifetime higher than configured in your PHP.ini and the session will be terminated as soon as the browser is closed.

Upgrade note for 2.0.0 from previous versions!

Version 2.0.0 requires an update in the database schema, so that additionally the date of the last access / hit on the page can be displayed ($page->lastPageHit). To make this possible, you have to do the update via the upgrade module, upload the ZIP itself and do an update directly via the backend AND DO A MODULE REFRESH DIRECTLY AFTER UPLOAD/UPDATE. If you do not do this, you will get an error that a column is missing in the database table.

>>>> All information about the changelog and bug fixings in the first post.

  • Like 2
Link to post
Share on other sites
On 2/10/2021 at 5:58 PM, ceberlin said:

Hi, today's 2.0 update killed the backend here on some installs... Reverting to 1.2.7 fixed it:

PDOException #42S22
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_phits.last_hit' in 'field list'

 

Please see upgrade note for 2.0.0 - After the update, you need to perform a module refresh directly so that the database schema is updated.

  • Thanks 1
Link to post
Share on other sites
On 2/10/2021 at 9:20 PM, Zeka said:

@David Karich Not sure, but probably it's more right to use 'return' instead 'exit()' across 'trackPageView' so we still get 404 page. Currently, I'm getting a blank page with 200 code when I directly access any page with prepended 'phcv1' segment with a template that added wether to API or automatic tracking templates list.

Hi @Zeka, a 404 should explicitly not be triggered. This is because the AJAX request would not be valid and would return a 404 and thus an incorrect status code. In addition, I think the discussion and issue was here before on the front pages, in previous versions every hit was registered as a 404 if you installed the 404 Page Logger or other 404 monitoring tools. Which then quickly flooded the log. So the only option was to set the priority close to 0 and prevent 404s. 🙂 

Link to post
Share on other sites

Hi @David Karich - thanks very much for this.

I just noticed that if you uninstall and reinstall, you get an SQL error because it's trying to create a table that already exists, so either the uninstall didn't clean things up properly (if that is the intention), or the install process needs to check to see if it already exists.

Also, just wondering if the AJAX approach could be reserved for sites running ProCache? Is there a need otherwise for doing it this way, rather than hooking on page render? There's a good chance I am overlooking something, but just thought I'd ask.

Another thought - have you considered a way for us to easily extend this to log click events to track users viewing PDFs etc? Maybe this really doesn't belong within this module and should be kept as something we implement on a case-by-case basis?

  • Like 1
Link to post
Share on other sites

@David Karich - on the issue of the AJAX call from the js file - turns out if you have url segments enabled for a template, when you view a page, the entire page's html is included in the response and sent to the browser along with the "Page Hit Counter: Tracked".

I can workaround it by adding:

if($config->ajax && $input->urlSegment1 == 'phcv1') exit;

to _init.php, but I think there needs to be a more elegant solution 🙂

I have read your section about "Notice: Tracking with URL segments", but I don't think that is really the issue here. I haven't defined my urlsegments yet (I will before the site goes live), but I don't think that will prevent this issue, will it?

Any thoughts?

 

Link to post
Share on other sites

Sorry, on a related note, if the template's urlsegment trailing slash is set to "yes" to force a trailing slash, you end up with two calls, so the module needs to check this setting and adjust the path accordingly.

681700061_ScreenShot2021-02-15at8_51_37PM.png.f39f12f20a7e415a241a9b6b9997d4c9.png

FYI - the reason I have that setting forcing the trailing slash is because I have urlsegments and pagination both turned on, and without it, URLs can end up broken.

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Sanyaissues
      I hadn't developed a website for a while, but here we are. It's a very simple minimalist website to showcase the latest work of Dominican Artist Patricia Abreu Mota.
      Site: https://patriabreu.com
      Modules:
      Procache ❤️ Seo Maestro Profiler Pro Lister Pro ProcessRedirects
    • By benbyf
      Hi, Looking to create form elements on a page–some input with a colection of form inputs and the appropriate labels and variables for that input. I've used ProForms in the past and rolled out my own when creating simply one off forms, but I wonder if anyone has found a good way of allowing form creation on page editing so that clients can adhocly make and edit forms?
      Thanks
    • By verdeandrea
      Hello,
      I am using ProCache v3.1.8 on ProcessWire 3.0.96.
      Everything worked fine in the past, but today I noticed that the css file serverd by procache gives a 410 error. 
      The file is there, I checked.
      I deleted the cached files, I deleted the css file, I looked into the .htaccess file looking for some clues about this problem but nothing worked.
      The only way i can see my website correctly again is disabling ProCache. 
      Has anyone any clue on what could be the cause of the problem or on what should I do to fix it?
      Thanks!
    • By Atlasfreeman
      Hi!
      I want to make a small site, a one page site.
      And i have this idea about doing 2 to 3 diffrent template that i can load into the index / home page.

      I want to do this with an array so that i can keep creating more topics (with the template) id needed.
      <?php include('./head.inc'); // include header markup ?> <?php $children = $page->get('template=onecolmn|twocolumn, sort=sort'); foreach($children as $child) { include($child); } ?> <?php include('./foot.inc'); // include footer markup ?>  
      As you can see i have to template wish i want to control from the backend.
      I know include does not work this way, put what is my other option to make an array that loads the whole page on an other pages.
       
       
    • By Liam88
      Hi All,
      New user over at Processwire and have been rebuilding my site based on this CMS.
      I have been able to find so many answers through Google but I'm a little stuck on this one.
      I have my services page -> services categories -> category children.
      An example of those would be - domain -> services -> ppc -> management
      I also have a set of tags which have different names - services-tag -> grow-your-traffic
      Under these tags I would have multiple links to pages such as ppc, seo, social media and so on.
      A second example would be - services-tag -> convert-your-traffic
      Under here i would have multiple links to pages such as CRO
      Now the set of tags are not visible on-site as they are only created to give overview content to the main services categories.
      Using the categories and the tags I am looking to produce a layout such as (i have also attached an image as an example:
      Tag_1 headline
      Pull all services categories linking to Tag_1
      Tag_1 snippet
      Tag_2 headline
      Pull all services categories linking to Tag_2
      Tag_2 snippet
      So far I have this snippet which is pulling in the tag content but unable to get the posts to show under each of the tags. 
      If i change the if and statement to "tags" instead of "tag" then all posts show under all tags. Where as i want it to show only the posts which are linked to that tag.
      <?php namespace ProcessWire; $tags = $pages->get("/categories-services/")->children(); // Gets the tags $posts = $pages->get("/services/")->children(); // Gets the services categories $link = $tags->ref_6; // Gets the tags and services categories link - under here you have pages_id (services cat id) and data (tags id) // Tag header and summary foreach($tags as $tag) { // This breaks down the tags into sections echo '<section id="services"> <div class="container"> <div class="row"> <h2 class="heading-1"><span>'. $tag->headline.'</span></h2> <p class="mb-5">'. $tag->summary.'</p> </div> <div class="row justify-content-around services">'; // Main services categories that link to the above tags if ($posts->id === $link->pages_id && $tag->id === $link->data){ foreach($posts as $service){ // This pulls in the services categories under the tag header. echo '<div class="card flex-card" id=""> <div class="card-img"> <a href="/'. $service->name.'" title="'. $service->name .'"> <img class="card-img-top" src="../assets/files/'. $service->id.'/'. $service->img_1.'" alt="'. $service->img_1.'" title="'. $service->img_1.'"></a> </div> <div class="card-body"> <h3 class="card-title">'. $service->headline.'</h3> <p class="card-text">'. $service->summary .'</p> <div class="card-action"> <a href="" title="'. $service->name .'" role="link" class="link">View service<span></span></a> </div> </div> </div> '; } } // Grey snippet text echo '</div> </div> </section> <div class="snip-2 light-grey"> <div class="container"> <div class="row text-center">'. $tag->get('grey') .'</div> </div> </div>'; } ?> I appreciate this is a long post but i'm trying to be clear as I appreciate everyone's time.
      Any insight into where I am going wrong is greatly appreciated.
      Liam



×
×
  • Create New...