Stats plugin / Hit counter

I decided to go for the session version:

if (c::get('stats.session', false)) {
    // Get the already visited pages
    $urls = s::get('stats', array());
    // User has visited this page already in this session. Do nothing.
    if (in_array($param, $urls)) {
    // User has never been here. Add the url and put back in the session storage
    $urls[] = $param;
    s::set('stats', $urls);

Thanks to the toolkit that was really simple :smiley:

1 Like

Hi, I have this route in my config.php and it seems to break kirbystats:

c::set('routes', array(
      'pattern' => 'clients/(:all)',
      'action'  => function($uid) {
      'pattern' => '(:any)(:all)',
      'action'  => function($u1,$u2) {
         $page = page($u1.$u2);

         if(!$page) $page = page('clients/' . $u1.$u2);
         if(!$page) $page = site()->errorPage();

         return site()->visit($page);

How can I fix this?

Bump! Anybody can help me with this? I’d really love to get this wonderful stats plugin working with my custom route :frowning:


It seems to be a bug. I’ve already issued it at GitHub.
As a workaround I deleted the stats.php from the plugins folder and added this line of code to my footer snippet.

snippet('stats', array('param' => $page->uri()));

@criuz: I wanted to use the router for the plugin in order to enable it for all pages without having to edit any of the templates or snippets. This means you can either use custom routes or kirbystats at the moment.

As a workaround @tobiasfabian’s solution should work. I’ll have to look at the router in more detail and see if I can find a nice and easy way to solve this.

1 Like

The solution @tobiasfabian provided did the trick! Thanks for this awesome plugin!

Is it possible to access these stats from the front-end? Like to display a list of popular blog articles, for instance.

The stats are saved in a page called kirbystats. In the frontend, you can access the data, but you have to create your own graph, if you need anything like that. To get the data:

// inside any kirby code, probably a snippet
$kirbystats = page('kirbystats');
$hits_per_page = $kirbystats->pages()->yaml();
$hits_per_date = $kirbystats->dates()->yaml();

```$hits_per_page``` then contains an associative array of pages and their total hit count, `$hits_per_date` the hits per data recorded by the plugin, independent of the page.

Cool, thanks. I basically just need to sort by hits, and pull the top pages, and filter by whether they’re part of the blog. Once I get that data from the kirbystats page, I should be able to do all that.

I keep reading this as ‘shits_per_page’ :stuck_out_tongue_closed_eyes:

The plugin looks good though :slight_smile:


Maybe there’s a way to integrate and actually measure that :laughing:

1 Like

How can I echo the content of the field “total-stats-count” in a template or a snippet?

This works:

// inside any kirby code
$kirbystats = $site->page('kirbystats'); 
$total = $kirbystats->total_stats_count();
echo $total;

For one of my Kirby sites it would be very nice, although the number of visitors would be counted.

You need to use underscores instead of minus.

Thanks for the very quick fix!

Hi … I’m using the plug-in on my site but it only counts hits on the home page but not on any other (sub)page. The site has two languages … any ideas, what I did wrong or how I can investigate this further …?

1 Like

@FabianSperrle and others:

Does anyone have an answer to the issue Plugin prevents Cache? #12 with Kirby 2.2.3?

I think

c::set('cache.ignore', array('kirbystats'));

does not work.

Many thanks!

What do you mean by “the cache does not work”?

The cache is flushed, whenever a page is updated, so whenever someone visits a page, the stats counter page is updated and the cache is flushed.

I should really add a note to the github repo that this was just an experiment and is not intended for production use.

Alternatively, maybe I can find a way to replace the update function with some hacky toolkit code to prevent the cache flush. I’m not sure whether I like that though… Have to take a closer look at the core to see how I can work around that.


… means, that I have tested, which says:


An array of URIs of pages, which should be ignored by the cache

But I found, that “which should be ignored by the cache” does not mean, that the cache.autoupdate-funktion interprets this value.

Before I had thought, that this would be consistent.

Why should the contents of a page be monitored (option autoupdate), if this page was not cached ( = ignored ) in the cache directory?

Otherwise I would have no problem…

Because the cache invalidation works the other way around. The cache needs to be flushed because other pages might need to be updated with the changed content, for example in navigations or a blog overview etc.