I’m writing a simple analytics plugin for Kirby 3. So far I’ve only processed page requests in the page template, but since I want to support cached pages as well, the processing of the request must be done before the page is actually served to the client.
I have tried a route that listens for any pages, but it may conflict with other routes in the future. I have also tried to process the request in my plugin’s index.php file. But the index.php of the plugin is also loaded for each page in the backend, and I couldn’t find a way to distinguish between a “normal” page requested by a visitor and a backend page in the panel.
So what I’m basically looking for is a place where I can put my analtyics code, something like a hook that is fired when a user requests a page. Maybe there’s a really obvious way to do this that I don’t see!
Thank you very much for the quick reply! The route hook seems to be a good place. What would be the easiest way to distinguish between “normal” page request and panel requests? For the route:before hook seems to be fired for every backend and api page.
Ah yes of course! For some reason I was only checking for the page id and the id seems to be the same for the pages home and panel home. With the path filtering everything works fine
I, too, use a route hook for a simple pageview counter plugin.
I had some issues with route:before (AFAIR it was something about the hook being triggered even though eventually the route would not resolve and hop to the next instead; this was about a very specific setup where the frontend would feature prettified URLs that did not reflect my Kirby page structure), counting some page views twice and eventually settled for route:after – the benefit being that this is only triggered by routes that have actually been processed.
Here’s the hook I use for registering page views, maybe it’s of value for you or somebody else.
'route:after' => function ($route, $path, $method, $result) {
// only for routes that yield a result
if ($result) {
// exclude requests that do not match a page
if ($path != '' && !kirby()->page($path)) {
return;
}
// do something to register the view for $path
}
}
I exclude requests where $path does not match an existing page, but that is probably more expensive (as page() leads to a request on the file system) than your substr-based string processing. I might actually adopt that in my next iteration
Thank you @sebastiangreger, this works great! I had the problem that also Error pages were beeing counted but your solution takes care of that now. I haven’t thought of kirby()->page($path). Might be handy if something with the substr path testing doesn’t work as expected.