Kirby has controllers but not snippet controllers (which Bricks has). Anyway, I will not talk about Bricks in this post but instead the need for snippet controllers in general.
Why a snippet controller
Normal controllers are used in templates. A template can contain like 10 snippets or more. To have the logic for all the snippets inside a big controller can be a bit messy after a while. Sure, you could lift things out and put them into a plugin instead, or you can bundle them to your snippets instead of your templates.
I now have a real live example for you. Don’t mind what this code does, it’s a breadcrumb snippet.
Snippet - Without snippet controller
It might look ok, but it’s still mixing logic and presentation quite a bit. If this snippet would be larger it would probably be even more messy and you need to do something about it.
<div class="breadcrumbs">
<a href="<?php echo url('bricks-ui'); ?>">Bricks</a>
<?php if( ! empty( $brick ) ) : ?>
<div class="breadcrumb-arrow"></div>
<a href="<?php echo url('bricks-ui/' . $brick); ?>"><?php echo $brick; ?></a>
<?php if( ! empty( $filename ) ) : ?>
<div class="breadcrumb-arrow"></div>
<a href="<?php echo url('bricks-ui/' . $brick . '?filename=' . $filename); ?>">
<?php echo $filename; ?>
</a>
<?php endif; ?>
<?php endif; ?>
</div>
Snippet controller
Now you may say that it’s even more code in just the controller than it’s in the snippet that contains logic. While that is true, it separates logic from presentation. I don’t need to open and close the php-tags all the time because I only work with the logic in here.
It’s probably possible to make this code much more optimized
<?php
return function($site, $pages, $page, $args) {
$data = array();
$steps = array('home', 'brick', 'filename');
foreach( $steps as $step ) {
$data[$step]['title'] = $args[$step];
switch($step) {
case 'home':
$data[$step]['url'] = url('bricks-ui');
break;
case 'brick':
$data[$step]['url'] = url('bricks-ui') . '/' . $args['brick'];
break;
case 'filename':
$data[$step]['url'] = url('bricks-ui') . '/' . $args['brick'] . '?filename=' . $args['filename'];
break;
}
$data[$step] = (object)$data[$step];
}
return array('data' => $data);
};
Snippet - With using the snippet controller
It’s about half the size and I keep things more DRY. Now this is very small example so the gain might not be very big but the more stuff you need the bigger the gain will be to separate logic from presentation.
<div class="breadcrumbs">
<?php foreach($data as $key => $item) : ?>
<?php if( ! empty( $item->title ) && $key != 'home' ) : ?>
<div class="breadcrumb-arrow"></div>
<?php endif; ?>
<a href="<?php echo $item->url; ?>"><?php echo $item->title; ?></a>
<?php endforeach; ?>
</div>
If you want to know more about how to use this approach read more about how it works in Bricks snippet controllers.
Update
I’ve updated both the snippet and controller because the code could be improved. Thanks @texnixe for the push.