Kirby Pre Controller

I’ve released yet another plugin. I hope some similar solution will be built into Kirby in the future.

Require Kirby 2.3 beta.

Kirby Pre Controller

  1. Let’s say you have a field name called status which is set to value unpublished.
  2. If the value is unpublished, redirect the current page to the error page.

It sounds really simple but it’s quite hard to solve. There are many other cases like this when you may need a pre controller as well.

Maybe it’s the first plugin that uses Page Methods.

So basically you need:

  1. Code that runs for every request.
  2. Which has access the the Page object matching the request’s URL.
  3. And which can do things like redirecting the page (returning a 301 response) and maybe all kinds of other things.

I’m not sure developers need a helper plugin for that, especially if it means calling that plugin’s code from a snippet. That seems rather brittle.

It looks like developers could just write their own “plugin” script to do whatever they need to do. The main issue is making sure that plugin script has access to the relevant Page object. After a few tries I was able to hack this:

<?php // site/plugins/not-really-a-plugin.php

// page() returns null in this context, but we can retrieve the current path
$path = kirby()->path();

// We should have a page object, or NULL for 404 pages
$page = page( $path ? $path : c::get('home', 'home') );

if ($page) {
   if ($page->status()->value == 'unpublished') {

There might be ways to return a 410 Gone response and page, too.

4. Support for multilanguage urls.

On a single language setup this solution might be ok. On a multilanguage setup it does not work. When writing echo $path; it prints something like this:


The plugin has support for multilanguage setup as well.

It looks like developers could just write their own “plugin” script to do whatever they need to do.

Yes they can! That’s just what I did.

I don’t think any browser has trouble with whitespace before the doctype. They may have trouble with non-whitespace, and probably with HTML comments, but whitespace is okay.

I would remove the whole doctype handling thing (it’s needless complexity), and just add a note to call the function before the doctype or any HTML content. This is perfectly fine in my experience:

<?php preController(); ?>
<!DOCTYPE html>

In any case, I would love to have a global controller that is run for all pages and before the template’s controller. Like you, when I read the Kirby docs saying that controllers/site.php would only run as a fallback, I was like “damn, that’s too bad”. :cry:

Something similar…

is there a way to define and set new filter types? if we could we could use them as middleware before certain routes (or before all of them). Either way, I would like to be able to define new filters.

I’m not sure how all the new browsers handle it, but I’ve had issues with whitespace before the doctype a few years ago myself. Maybe the problem is not a problem anymore.

Always include one of the doctypes mentioned here as the very first thing in all of your HTML documents.

So, I’m not convinced about it yet. I’ll read more about whitespace and think about what approach to take.

In any case, I would love to have a global controller that is run for all pages and before the template’s controller.

Agree! Then I would love to shut this plugin down. :slight_smile:


You can define custom collection filters or maybe you are talking about something else?

2 posts were split to a new topic: How to define route filters

I agree with you here and have opened a feature request issue.

It’s not, at least since IE8 (maybe IE6-7 had issues, but I worked on CSS for those browsers too and I don’t remember this issue). Other issues you may have seen are IE 8-10 going in Compatibility mode, but that would be for other reasons (local network, intranets, X-UA-Compatible headers or lack thereof).

For me what you just created is a global middleware.

Yes, I guess I did, in your terms. The pre-controller will run exactly before the html is rendered.

But I can’t find anywhere to define new “filters” (or middleware) for routes… or globally.

Maybe @lukasbestle answered it already.

My biggest problem with the routes is that they run before the $page object created. Often I want to do something on the current page, redirect it or do something else depending on some field value or so. For now I’ll do these things with my plugin until something greater is built in, like the feature request issue that @lukasbestle have added.


You sound convincing. I will try modern browsers, including on mobile devices (at least Android) and if it works, maybe remove that ugly string input.

This plugin has been rewritten and renamed. Now it’s a pure piece of art!