mangopo

Page view counter and cache

Recommended Posts

My site's articles use a page view counter that makes it possible to list top 5 most viewed articles. After enabling cache for all pages it no longer counts views. Is there any way to fix this?

Share this post


Link to post
Share on other sites

Depends on how this page view counter works. You could either work with a ajax request to an uncached page to update the counter or you use a (then rather complicated) construct with markup cache.

Share this post


Link to post
Share on other sites

This is the code in the blog article template:

$page->setOutputFormatting(false);
$page->views = $page->views+1;
$pages->saveField($page, 'views');
$page->setOutputFormatting(true);

Share this post


Link to post
Share on other sites

Well, as suggested: I would put this code in a page with a non cached template:

<?php
$id = $sanitizer->text($input->get->id);
$whichPage = $pages->get($id);
$whichPage->views = $whichPage->views+1;
$whichPage->saveField($whichPage, 'views');

And in your pages / other templates you place something like this (jQuery assumed):

<script>
$.get("/mycounter/", {id: <?= $page->id ?> } );
</script>

"mycounter" would be your counter page with the counter template.

[totally untested]

  • Like 2

Share this post


Link to post
Share on other sites

I like MadeMyDay's solution. A couple other possibilities are:

1. Use MarkupCache rather than template caching. That way you can cache just the parts of the output that you want to, and leave the things like your counter uncached.

2. Create an autoload module. Add a ready() function to it and have that function increment the counter of $this->page (using the same method you are already doing).

Share this post


Link to post
Share on other sites

I'm asking since i am not that PHP pro to get my head around this.

I need two things for a minimal add system with simple image banners to list

a) clicks (That part should be easy since i've a part_add.php template that would be called on clicking a add ->set counter var +1 and redirect to $page->link

b) views (That's the tricky part....)

mixed things up....since views are the simple part on calling a template count up should be easy.....and the "click" part is that who have to solved different...but i've searched stackoverflow....and find something to play.... ;)

i thought embedding the adds via simple snippet or function to get random adds in the slots....but how i could count those views?

what i've to think about the template design - ok i need a additional counter field for the views but

how i get those if i simple run a find("template=part_add, limit=5,sort=random") in a foreach...is there a chance to track the views simple or need this a more complicated setup?

Any hint or tipp on this would be appreciated.

regards mr-fan

Edited by mr-fan

Share this post


Link to post
Share on other sites

Hmm I could use a php page to handle the redirects and the click counting?

Know someone a good example for such things? Or any hints on this topic?

From mobile - regards mr-fan

Share this post


Link to post
Share on other sites

Do a post with javascript with the ID of the page to a not cached page. On the not cached page get the incremental number of the visited Page (an integer field) and save that plus 1 back to the Page that is viewed.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks Martijn - for show me my issue....just some mixed thinking...i'm sometimes a very distracted person - so i often need the right hint in the other direction :frantics:

Could solve this for now....an additional question.

What would be a good solution to store an additional date to every count - so that hits per month or something else whould be possible...this would need a repeater? Or is there a more performant way for such simple DB tables to connect simple entry with a date - since this would grow to many entries for a reapeater at time?

What could be best practise in this case. Counting views and clicks with a timestamp would only be a nice to have - but would result in nice little stats.

regards mr-fan

Share this post


Link to post
Share on other sites

1 suggestion:

For every view store a page in a folder page called stats (or whatever).

The page to store has a pagefield (single) to store the viewed page based on the ID posted with Javascript.

For the date you could used a dedicated field or just use the title/name of the page.

  • Like 1

Share this post


Link to post
Share on other sites

What would be a good solution to store an additional date to every count - so that hits per month or something else whould be possible...this would need a repeater? Or is there a more performant way for such simple DB tables to connect simple entry with a date - since this would grow to many entries for a reapeater at time?

I would advice against repeaters. This would definitely become a performance issue in the long run.

What @Martijn suggested sounds like a possible solution too, though that would require creating a lot of pages. Depends on how popular your site is, but this sounds like another scalability issue to me, and at the very least it would create unnecessary load on your server.

Table field from the (commercial) ProFields module bundle would be a great fit for this task. It creates a database table of its own, which would make sense here. Another option would be a new module that does pretty much the same, though that would be more complicated to set up.

Unless there's something I'm completely missing here, I would actually suggest a completely different route. What you're doing here is trying to recreate a subset of what Piwik and Google Analytics already do extremely well. That doesn't make any sense to me at all.

Set up Google Analytics and let it handle collecting data. If there's a need to pull the data to your site and display it there (instead of within GA GUI), use Process Google Analytics or query the data via GA API. There are PHP libraries available for doing that, so it's not that much of a hassle really. 

  • Like 4

Share this post


Link to post
Share on other sites

In my former CMS there was a little counter addon that setup a little table with views/clicks and timestamp...that was easy to use for small addstatistiks....but i'll not create a separate tracking system if i have one that could do the job.

For my smaller websites i simple use the "views" counter of the guests group and show them in a simple Lister called "visitorstats" so the more or less editors can see counts of the homepage and importand pages for visitors....nothing facy but some small help and it's a single field on every page that is incremented on view.

Since i've a PIWIK Installation ready to go i could get hands dirty on the event tracking API.....

http://developer.piwik.org/api-reference/tracking-api

even more simpler seem the content tracking guide:

http://developer.piwik.org/guides/content-tracking

it's been a while since i've worked on the "piwik side of things" but this is reading even better to get some stats on a PW admin page:

http://developer.piwik.org/guides/reporting-api-tutorial

Thank you very much Teppo and Martijn for your thoughts!

Very helpful answers as ever.

Best regards mr-fan

Share this post


Link to post
Share on other sites
$page->setOutputFormatting(false);
$page->views = $page->views+1;
$pages->saveField($page, 'views');
$page->setOutputFormatting(true);

this codes work well but every page refresh counter increase. how can i use it for each session?

Share this post


Link to post
Share on other sites

ahh yea i use this codes and page refresh does not increase view. it looks only session :)

$key = "pageview" . $page->id; 
if(!$session->$key) { 
	$page->Counter += 1;
$page->of(false);
$page->save('Counter');
$page->of(true);
   $session->$key = 1;  }
  • Like 1

Share this post


Link to post
Share on other sites
On 8/11/2012 at 12:13 AM, ryan said:

2. Create an autoload module. Add a ready() function to it and have that function increment the counter of $this->page (using the same method you are already doing).

I'm trying this option, but I can't seem to get it to work.

I've tried:

    public function ready() {
        $this->addHookAfter('Page::render', $this, 'updatePageViews');
        $page = $this->page;
    }

    public function updatePageViews($event) {

        /** @var Page $page */
        $page = $event->object;

        // don't add this to the admin pages
        if ($page->template == 'admin')
            return;

        if ($page->hasField('pageViews') and $this->user->isGuest) {
            //Update the number of page views for current page, but only visitor views not admin.
            $page->of(false);
            $page->pageViews ++;
            $this->pages->saveField($page, 'pageViews');
            $page->of(true);
        }
    }

and this way:

    public function ready() {
        $page = $this->page;
        if ($page->hasField('pageViews') and $this->user->isGuest) {
            //Update the number of page views for current page, but only visitor views not admin.
            $page->of(false);
            $page->pageViews ++;
            $this->pages->saveField($page, 'pageViews');
            $page->of(true);
        }
    }

But neither of them seem to do anything with template caching enabled.

Any idea what I'm doing wrong?
 

Edit: I found the problem isGuest needs brackets, ie isGuest()

Edited by Kiwi Chris
solved problem

Share this post


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.