A different approach to the Kirby content() method?

If you work with Kirby you are familiar with the concept of creating fields in a page blueprint and accessing it in your page template. Usually you end up with something like this:

<?= $page->myField() ?>

As long as your field name does not match a reserved word you’re fine. But as soon as your field name has the same name as an existing page method you need to make use of the content() method (and everything is fine again).

<?= $page->content()->myField() ?>

Since I use custom page methods on a regular basis, I prefer to use the content() method for every page field. No matter if there’s a naming conflict or not. In this way it is easier to me to differentiate between page methods and fields.

<?= $page->url() ?>
<?= $page->customPageMethod() ?>
<?= $page->content()->myField() ?>

Unfortunately it requires more typing and (in my opinion) it's a bit harder to read as well.

Introducing a $content variable

Lately I had the idea to create a custom $content variable and use it across all page templates. The right place for additional variables for your page template is a controller. Every page template can have its own controller. But there is also a general site controller which is useful if multiple templates share the same logic.

/site/controllers/site.php

<?php

return function ($page) {
  return [
    'content' => $page->content(),
  ];
};

With this few lines it is now possible to use a $content variable as a replacement of $page->content() across all page template. The page template example from above can be be changed to the following. It might look unusual at first but I think i’ll give it a try.

<?= $page->url() ?>
<?= $page->customPageMethod() ?>
<?= $content->myField() ?>

Please be aware that, as soon as you create a custom controller for a single page type, you need to define the $content variable again. Since it’s just a single line of code, I think it’s not a big deal. If you have more variables you want to share, check out this tutorial about how to create a shared controller setup by Manu Moreale. By the way, with Kirby 5 the shared controller setup will no longer be necessary because the general site controller will automatically be merged.

One more thing …

As Florens mentioned on Mastodon, this approach only works while $page represents the current page, because the variables defined within the controller are only available in the corresponding page template. That’s a valid point you have to keep in mind.

But in combination with custom view modes it still might be a way to go because if you use these view modes consequently it will probably reduce the amount of situations where $page is not the current page. I will try both in combination and might come back with a report of my findings.

Sources


CMS Kirby PHP #Template

Replies

  • moinframe | Justus

    @flokosiol Ohh, not a bad idea. I always found it a bit confusing, especially for people new to Kirby, to understand which methods are real methods and which are just fields. Might try your approach!

  • Felix Niklas
  • Florens Verschelde

    @flokosiol @getkirby Interesting, but I think in my last big Kirby project, more often than not I was working with pages which are not the current page (any page from a list: navigation, child pages, related pages, etc.). So always minding when I can use `$content` vs `$item->content()` would be more confusing than helpful.

    With time I kinda shy away from using the injected `$kirby`, `$site` and `$page` variables, often using `kirby()`, `kirby()->site()` or `page()` instead. If only because those are available in more contexts.

  • nilsmielke ⁂

    @flokosiol @getkirby Interesting approach. Will try and see, what “feels” better.

  • Luke Dorny :CameraPolaroid:

    @nilsmielke @flokosiol @getkirby yes! This was a Kirby concept I feel like I bumped into from time to time when I would use page methods that I thought were my own. The content clarifier always seemed unnecessary, but your article clears up for me me understanding of it. Thanks!
    Also, excitingly, v5 shares the site controller site wide! Love this.

  • Richard the Brave 🇨🇦

    @flokosiol @getkirby Really enjoying your posts lately!

  • Luke Dorny :CameraPolaroid:

    @flokosiol oh, my goodness, very clever. At times I realized if only fleetingly that I was using a shortcut for content() but not in time to face object collisions with no clear way to resolve the issues. I really appreciate articles like this. Thank you. @getkirby

  • Luke Dorny :CameraPolaroid:

    @flokosiol @getkirby is that the right term for this? Object collisions? I don’t even know.

  • Flo

    @Luke @getkirby I don’t know, tbh. Unfortunately, I don't have the theoretical background to answer this question. 🤷‍♂️

  • Luke Dorny :CameraPolaroid:

    @flokosiol No problem. I'm anxiously engaged in improving my understanding of programming, but it's slow-going for me. :)

  • Flo

    @Luke It‘s not about the speed, it’s about the progress and the understanding. So keep learning! It’s what we all do. 🙃

Latest

Insignificant vibes?

Some thoughts about vibe coding in the context of coding for fun.

Featured

#FIXME! git pre-commit hook

I use #FIXME comments all the time in my code and I am sure you do, too. Some of these comments stay for a really long time until they finally get fixed. But sometimes there are temporary changes in my code which definitely must not go live!

pageview counter pixel