Hi, i know i can pass variables to snippets like that:
snippet('snippetname', ['helloWorld' => 'Hello World!'])
But how to define a complete Controller linked to the Snippet?
The only solution i found is using a site.php controller but i think it will get unorganized if i have more than one snippet which needs a controller.
Is there a good way to solve this?
You can overwrite the snippet component and add a controller in there.
Something like this works as a plugin.
<?php // site/plugins/site/index.php
use Kirby\Cms\App as Kirby;
use Kirby\Toolkit\A;
use Kirby\Toolkit\F;
use Kirby\Toolkit\Tpl as Snippet;
Kirby::plugin('lukaskleinschmidt/site', [
'components' => [
'snippet' => function (Kirby $kirby, string $name, array $data = []) {
$snippets = A::wrap($name);
foreach ($snippets as $name) {
$name = (string) $name;
$file = $kirby->root('snippets') . '/' . $name . '.php';
if (file_exists($file) === false) {
$file = $kirby->extensions('snippets')[$name] ?? null;
}
if ($file) {
break;
}
}
return Snippet::load($file, snippet_controller($name, $data));
}
],
// You could also register controllers here
'snippets' => [
// Register a callback
'snippetname.controller' => function (array $data = []) {
return array_merge($data, [
…
]);
},
// Register a file
'snippetname.controller' => __DIR__ . '/snippets/snippetname.controller.php',
]
]);
function snippet_controller(string $name, array $data = []): array
{
$name .= '.controller';
$file = kirby()->root('snippets') . '/' . $name . '.php';
if (file_exists($file) === false) {
$file = kirby()->extensions('snippets')[$name] ?? null;
}
if (is_string($file) && is_file($file)) {
$file = F::load($file);
}
if (is_callable($file)) {
$data = call_user_func($file, $data);
}
return $data;
}
A controller could then look like this.
<?php // site/snippets/snippetname.controller.php
return function (array $data = []) {
return array_merge($data, [
…
]);
};
Thanks for your answer. This isnt really what i want to Archive. My Goal ist to outsource everything Like snippets, Templates, Controllers and scss into a Plugin, so that i Just have to Touch the Plugin to make Changes for my customer.
For example ‘snippets/navigation-default.twig’ is extended by ‘snippets/navigation.twig’ in the Plugin. Same for other Stuff.
If i now make a generell Change in my Template i have to think about the Controller folder because this isnt outsorced in my Plugin.
So the Goal ist to outsource the Controller into a Plugin.
With this approach you can actually register the snippets and controllers in a plugin.
It is just of matter of the correct naming.
Kirby::plugin('your/plugin', [
'snippets' => [
'header' => __DIR__ . '/snippets/header.php',
'header.controller' => __DIR__ . '/snippets/header.controller.php',
]
]);
1 Like
I finally found the time today and packed it into a tiny plugin.
2 Likes
Hi, thanks for your message. I will take a look at it