Shared Controllers
A simple example
We'll use the <title>
and <meta name="description">
tags as an example. The easiest way to add those two tags to our site would be to add them directly into the header.php
snippet. Something like this:
That's a perfectly fine and reasonable solution. But what if we want to show a slightly different title for the homepage for example?
This is already starting to look ugly and things will only get messier if we start adding more logic or other tags. It then makes sense to move the logic from the snippet into a controller.
Let's do that.
Setting up the default controller
The first thing we need to do is set up our default controller. To do that we'll make use of the site.php
controller that will also act as a fallback when no controller is found for a particular template.
Now that the logic to fetch the correct data has been moved inside the controller we can simplify the header.php
snippet.
Excellent, this is already looking a lot cleaner. Now we need to implement the different logic to create the <title>
tag for the homepage. To do that we'll use a home.php
controller. You'd think that doing something like this would be enough to achieve our goal.
But if we do that and we navigate to our homepage we'll get presented with an error.
That's because we now have a controller for the homepage, and Kirby will use that instead of our fallback one. An intuitive solution would be to simply copy and paste the same line of code from the site.php
controller into the home.php
controller but that goes against the DRY principle.
Setting up the shared controller
This is where the concept of the shared controller becomes useful. Rather than copy and pasting the same code, we'll first use the $kirby->controller()
method to get the data from the site.php
controller and store it in a variable.
More info on the controller()
method can be found in the docs.
Then we'll overwrite the content of our title tag with the different bit of logic we want to use for the homepage.
And finally, we'll merge the content and return it as an array that will then get passed to the template
Be careful, when merging the two arrays, to pass the $shared
array as the first parameter to the A::merge()
function. This is important because otherwise your new data won't overwrite the content coming from the default controller.
Final shared controller
The final home.php
controller will look like this:
And that's it. We now have a place to store all the data that is shared among all our templates and we have a way, using controllers, to overwrite what needs to be overwritten on a template by template basis.
Closing thoughts
In this example we've used the site.php
controller to share content across the entire site but the same concept can be adapted to share content across a more local scope.
For example, in a blog you could have different controllers for different type of blog posts...
...and you can leverage the method described in this guide to share the content of the post.php
controller with the other controllers.
To do that you need to pass the correct controller name to the controller()
function and you're done.