Hi @Norreco
I think that, like everything, the answer will be, it depends, unfortunately.
But may be I can help you with your decision to achieve your problem.
First of all, the main question (I guess) is:
When should the cache be cleared?
- Only one time per day.
If that’s the case, may be you don’t really need to be worry about it and use the expiration third parameter in the set method;
$timezone = new DateTimeZone("Europe/Copenhagen");
$now = new DateTime("now", $timezone);
$end = (new DateTime("today", $timezone))->setTime(23, 59, 59);
$diff = $now->diff($end);
$minutes = $diff->h * 60 + $diff->i;
$cache->set('key', $content, $minutes);
With the example, the cache will only last for the current day, and the next day, the first user to consume the content will cache it for the current day.
- If the events change multiple times in the same day
If that’s the case, you need to invalidate the cache when an event is created, updated, duplicate or deleted.
For this case, hooks are your best friends.
// site/config/config.php
return [
'hooks' => [
'page.create:after' => function (Kirby\Cms\Page $page) {
$this->cache('pages')->remove($key);
},
'page.update:after' => function (Kirby\Cms\Page $newPage, Kirby\Cms\Page $oldPage){
$this->cache('pages')->remove($key);
},
'page.duplicate:after' => function (Kirby\Cms\Page $duplicatePage, Kirby\Cms\Page $originalPage) {
$this->cache('pages')->remove($key);
}
'page.delete:after' => function (bool $status, Kirby\Cms\Page $page) {
$this->cache('pages')->remove($key);
}
]
];
Now the hooks will keep your cache cleared when there is a page change. In the past example, every time there is a page change, it will clear the cache; you should only dispatch when the exhibitions or projects are updated.
The next question for me will be:
Where should I have to put the code?
Here you have a couple of places too:
- Model
For me every type of page should have a cache, and every page, should be responsible of their content.
// site/models/exhibitions.php
<?php
use Kirby\Cms\Page;
class TravelPage extends Page
{
public function getExhibitionChildrenCache()
{
$exhibitions = $this->children()->listed();
//your logic for events
kirby()->cache('pages')->set('exhibitions', $content, $minutes);
}
}
And the same for your `projects`, now in your page you can access them with:
$content = site()->find('exhibitions')->getExhibitionChildrenCache();
- Controller
If a model is confusing, you can always use this in a controller:
<?php
use Kirby\Cms\App;
use Kirby\Cms\Page;
use Kirby\Cms\Site;
return function (Page $page, Site $site, App $kirby) {
$exhibitions = $site->find('exhibitions')->children()->listed();
//your logic for events
kirby()->cache('pages')->set('exhibitions', $content, $minutes);
return [
'exhibitions' => $content,
];
};
Now in your template will have an $exhibitions variable with your cache.
For me I will do (for model or controller) a validation, to get always the cache data:
if (! $kirby->cache('pages')->exists('exhibitions')) {
//your logic for events
$kirby->cache('pages')->set('exhibitions', $content, $minutes);
}
$exhibitions = $kirby->cache('pages')->get('exhibitions')
If you have control of everything
What I mean is that if you can install a cron job on the server, you can use composer for your Kirby installation, and you can also install Kirby CLI as a global dependency.
If you can do this, you can use Kirby Scheduler
With that, the cache and clearance could be trivial.
// site/config/config.php
use Beebmx\KirbScheduler\Schedule;
use Carbon\Carbon;
return [
'beebmx.scheduler' => [
'timezone' => 'Europe/Copenhagen',
'schedule' => function (Schedule $schedule) {
$schedule->call(function() {
$now = Carbon::now('Europe/Copenhagen');
$end = $now->copy()->endOfDay();
$minutes = (int) ceil($now->diffInSeconds($end) / 60);
//your logic for events
kirby()->cache('pages')->set('exhibitions', $content, $minutes);
})->daily()->at('5:00');
},
],
];
Notes
- I would try to avoid mixing code (logic with templates).
- Define when the cache will be stored and when it will be cleared.
- Kirby offers multiple ways to implement code; use the one you feel comfortable with.