But just exactly how do boards look so nice all the time? It's the use of driver objects that can strictly control how board content is laid out. The easiest way to understand this is to look through how Atomik's Blog board is configured, and learn lessons from that.
Blog Template Driver
The Concrete\Core\Board\Template\Driver\BlogDriver
class informs Concrete that it itself contains 5 slots:
public function getTotalSlots(): int
{
return 5;
}
Additionally, it controls the display of slot number 1 in a very particular way, by implementing the getLayoutPlanner
method. This is an optional method available to the blog driver class.
public function getLayoutPlanner(): ?PlannerInterface
{
return new SlotLayoutPlanner([
'1' => ['blog_image_left']
]);
}
The SlotLayoutPlanner
class is a simple class meant to tie a particular slot in a board template to a particular board slot template. What does this means? It means that no matter how many times you regenerate the Atomik blog board, you'll aways get a left-image content element in the first slot, because the only slot template that layout planner will allow to be placed within the slot 1 is the blog_image_left
slot template.
So let's look at the blog_image_left
slot template driver, found at Concrete\Core\Board\Template\Slot\Driver\BlogImageLeftDriver
. It informs the system that it contains one content slot:
public function getTotalContentSlots(): int
{
return 1;
}
And it also informs the system that within its single content slow, only the content objects with the blog_image_left
summary templates may be placed. This is through the use of the slot filterer object:
public function getSlotFilterer(): ?FiltererInterface
{
$filterer = new SummaryObjectFilterer();
$filterer->registerSlot(1, [
'blog_image_left',
]);
return $filterer;
}
This is similar to the board planner object, but it works with summary templates.
Let's contrast this with the Concrete\Core\Boared|Template\Slot\Driver\BlogThreeUpDriver
class. When the slot template blog_three_up
is placed within a board template slot, **three* content objects will be placed within its content slots:
public function getTotalContentSlots(): int
{
return 3;
}
Additionally, not just any summary templates may be used for these content objects – only the blog_entry_card
summary template will be used for the items in these content slots, because that's what the slot filterer decrees:
public function getSlotFilterer(): ?FiltererInterface
{
$filterer = new SummaryObjectFilterer();
$filterer->registerSlot(1, [
'blog_entry_card',
]);
$filterer->registerSlot(2, [
'blog_entry_card',
]);
$filterer->registerSlot(3, [
'blog_entry_card',
]);
return $filterer;
}
When you get down to the details of the blog_entry_card
template, it's relatively straightforward. From concrete/themes/atomik/elements/summary/templates/blog_entry_card.php
:
<?php defined('C5_EXECUTE') or die("Access Denied."); ?>
<div class="ccm-summary-template-blog-entry-thumbnail">
<a href="<?=$link?>" class="card">
<div class="position-relative">
<div class="card-img-top ccm-summary-template-blog-entry-thumbnail-image-overlay"></div>
<img class="card-img-top" src="<?=$thumbnail->getThumbnailURL('blog_entry_thumbnail')?>">
</div>
<div class="card-body">
<h5 class="card-title"><?=$title?></h5>
<?php if ($date) { ?>
<p class="card-text text-center"><small class="text-muted"><?=date('F d, Y', (string) $date)?></small></p>
<?php } ?>
</div>
</a>
</div>