Building a component based style guide for Kirby (2)
In the first part of this series I wrote about the concept of frontend components and how they can be used in Kirby templates. But this was just the basis and nothing really new. In this second part I want to show how to build a style guide overview page on top of it.
There will be another follow up blog post about how to extend it furthermore to have single pages for each component with additional information.
Plugin
To keep all the code organized we create a custom plugin. The first step is to add a new folder with an index.php
file to the plugins directory.
site/plugins/styleguide/index.php
Routing
To ensure that the style guide can be reached at mydomain.com/styleguide
, we need to register a route. This can be done in the plugin definition inside the index.php
file. But to keep this file clearly organized, the route itself is defined in a separate site/plugins/styleguide/routes.php
file. Nevertheless Kirby's static Kirby::plugin()
method needs to know about it.
<?php
Kirby::plugin('flokosiol/styleguide', [
'routes' => require_once('routes.php'),
]);
The routes.php
file contains a single custom route. This file is later filled with additional content, but for now this is sufficient. We also check for a logged in user to keep the content private. Of course you can omit this check if you want to keep it open to everyone.
site/plugins/styleguide/routes.php
<?php
return [
[
'pattern' => 'styleguide',
'method' => 'get',
'action' => function () {
if (kirby()->user()) {
return new Page([
'slug' => 'styleguide',
'template' => 'styleguide',
'parent' => kirby()->site()->homePage(),
'content' => [],
]);
}
die;
}
],
];
Template
The route definition above instructs Kirby to use the styleguide
template. Since it does not exist yet, we have to add it to our plugins folder and extend our plugin definition in the index.php
file accordingly.
<?php
Kirby::plugin('flokosiol/styleguide', [
'routes' => require_once('routes.php'),
'templates' => [
'styleguide' => __DIR__ . '/templates/styleguide.php',
],
]);
The basic structure of the template file can pretty much look the same as every other template file in your installation. Personally, I like to use a snippets/layout/html.php
file which holds the markup for header and footer and a slot for the content. If you work with Kirby regularly this will probably look familiar to you.
site/plugins/styleguide/templates/styleguide.php
<?php snippet('layout/html', slots: true) ?>
<section class="styleguide">
<h1>Style Guide</h1>
<!--
#FIXME: some kind of navigation
#FIXME: preview of all components
-->
</section>
<?php endsnippet() ?>
The HTML structure inside this template is totally up to you and your needs. I like to wrap everything in a styleguide
CSS class. It allows me to make style adjustments which are limited to the style guide without any side effects to the “real“ frontend components.
We should now be able to visit mydomain.com/styleguide
and see the template in action. But not more than that.
Snippets
Oh no, more snippets!? Yes! Before we can add the missing parts in our template, we have to add some style guide content. Let’s create a snippet folder inside the regular Kirby folder structure (outside of the plugin) and use the teaser
frontend component from the first part of this series.
Why outside of the plugin? These snippets are coupled tightly to the project but we want to keep the plugin reusable and keep custom code away if possible. The template file from above is already something which needs to be adjusted for every project. But the plugin won’t work without it, so we have to include it. In contrast, the snippets can be easily separated.
site/snippets/styleguide/teaser.php
<?php
snippet('component/teaser', [
'modifier' => '',
'headline' => 'This is a Teaser',
'image' => '<img src="https://placehold.co/600x400" alt="Placeholder image" width="600" height="400" >',
'text' => '<p>Et quis cillum Lorem irure eu. In irure officia labore Lorem irure esse adipisicing proident. Nulla fugiat pariatur sunt nostrud nostrud.</p>',
'url' => '#',
]);
?>
By using static content here, it is possible to build the frontend components and the style guide before any Kirby backend logic or CMS content exists. If you already have access to some real data stored in Kirby, you can of course query and use that as well.
Static snippets
There are use cases in my setup where I don’t use frontend components. One is the styling of rich text which comes from an editor field of the CMS and includes only basic HTML elements. I just wrap these elements inside a .text
class so there’s no need for a dynamic component.
site/snippets/styleguide/text.php
<div class="text">
<h1>Headline 1</h1>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. <a href="#">Link</a> assumenda <strong>bold</strong> voluptatum <em>italic</em> nulla modi repellat earum necessitatibus! Fugit autem debitis, dolore perspiciatis, ex explicabo delectus laboriosam vitae reiciendis, dolorum temporibus quas soluta!</p>
<ul>
<li>Veniam aliqua tempor cillum amet exercitation minim incididunt ipsum.</li>
<li>In mollit commodo magna id magna fugiat culpa dolor culpa laboris cillum. Deserunt enim cillum non pariatur in aute sint nostrud cupidatat. Anim do aliqua nulla minim officia ad consectetur ea sit commodo reprehenderit sit laborum quis.</li>
<li>Magna sunt exercitation et labore veniam. Incididunt tempor qui eu consectetur ullamco reprehenderit aliqua exercitation sit reprehenderit pariatur.</li>
</ul>
<ol>
<li>...</li>
</ol>
<h2>Headline 2 (maybe with additional text to force a line break)</h2>
<p>And so on …</p>
<!-- and so on ... -->
</div>
The second use case for a static style guide snippet could be the preview of buttons. In my opinion, it makes no sense to build an abstracted frontend component, as experience has shown that this tends to complicate matters. Especially, if you want to style anchor elements as well as button elements. But I know developers who like to use a component here as well. Your choice!
site/snippets/styleguide/button.php
<?php
$buttons = [
'primary' => 'Primary',
'secondary' => 'Secondary',
];
?>
<?php foreach ($buttons as $variant => $title): ?>
<div>
<a href="#" class="button button--<?= $variant ?>"><?= $title ?> Link</a>
<button class="button button--<?= $variant ?>"><?= $title ?> Button</button>
<button class="button button--<?= $variant ?>" disabled><?= $title ?> Button (disabled)</button>
</div>
<?php endforeach; ?>
Of course, this could be extended to several sizes or other button variations.
Detecting the snippets automatically
All snippets inside the site/snippets/stylegiude/
folder should be detected and fetched automatically and listed on our style guide page. Therefore we create a custom site method. Like before, we keep the code out of the index.php file as well and collect all custom methods in a separate folder.
<?php
Kirby::plugin('flokosiol/styleguide', [
'routes' => require_once('routes.php'),
'siteMethods' => require_once('methods/site.php'),
'templates' => [
'styleguide' => __DIR__ . '/templates/styleguide.php',
],
]);
site/plugins/styleguide/methods/site.php
<?php
return [
'styleguideModules' => function() {
$modules = [];
$moduleFiles = Dir::read(kirby()->roots()->snippets() . '/styleguide');
foreach ($moduleFiles as $fileinfo) {
$filename = F::name($fileinfo);
$modules[$filename] = Str::upper($filename);
}
return $modules;
},
];
With Kirby’s Dir::read
method we can scan the folder of the style guide snippets and find all the files in alphabetical order. The F::name
method removes the file extension and the name of every snippet is pushed into an array which looks like this:
$modules = [
// ...
'button' => 'BUTTON',
'teaser' => 'TEASER',
'text' => 'TEXT',
// ...
];
Add the missing parts to the template
The newly created site method can then be used to generate the overview of all components based on the example content of the style guide snippets. As soon as the list of components grows, a little jumpmark navigation at the beginning of the page can increase the usability significantly.
<?php snippet('layout/html', slots: true) ?>
<div class="styleguide">
<h1>Style Guide</h1>
<?php # jumpmark navigation ?>
<?php if ($styleguideModules = $site->styleguideModules()): ?>
<ul>
<?php foreach ($styleguideModules as $module => $title): ?>
<li>
<a class="button" href="#<?= $module ?>"><?= $title ?></a>
</li>
<?php endforeach ?>
</ul>
<?php endif; ?>
<?php # list of all components based on the style guide snippets ?>
<?php foreach ($site->styleguideModules() as $module => $title): ?>
<a href="#" id="<?= $module ?>" tabindex="-1"></a>
<?php snippet('styleguide/' . $module) ?>
<?php endforeach ?>
</div>
<?php endsnippet() ?>
Depending on the layout of your site it is important to decide wether to add the markup of a container/wrapper element to the template (which will affect the whole page) or to each style guide snippet individually. The latter is the better choice if you have components which go full width and other which don’t.
Whats next?
In the next part of this series I demonstrate how to set up individual pages for each component, which can be used to add additional content or component variations.
Sources
CMS Kirby PHP #Style guide #Components #Routing
What do you think?
Let's discuss on Mastodon