Kirby + Patterns = <3
When I heard about Brad Frost's Patternlab for the first time at beyond tellerrand I was intrigued. The idea of splitting your design work for a website into simple modules or patterns isn't new and starts to become more and more of a standard. But organizing this into a very visual styleguide/patternlab seemed to make so much sense. Brad also introduced a very interesting approach with his separation of modules into categories, such as atoms, molecules and organisms.
I started porting Brad's patternlab app to Kirby, but it never really made it to something polished and it turned out for me after using it for Kirby's panel UI, that it's actually a pain in the ass to maintain such a pattern collection.
The problem of patternlab
The problem with such a styleguide or patternlab is that it exists next to the real thing. When you change something in your code base you also have to update the particular code for the pattern in patternlab. To be honest I went very quickly from being excited to stop using it entirely.
But what if there was a way to combine the process of creating patterns, describing them and building your frontend. And what if your frontend was actually feeded by your patternlab. Instead of maintaining two code bases you would just have one place to write your frontend code, package it in handy modules and update them on the go. Your patternlab would always be up to date with every change of your site.
I sat down the other day and started to draft a very early version of such a solution with Kirby. It turned out to be much easier than I thought and brought some very interesting additional opportunities.
The code I came up with is very alpha so far and just a tiny Kirby plugin. Here is what it does:
- Patterns are stored in a folder called patterns (crazy, right?)
- Each pattern gets its own folder. Folders/patterns can be nested.
- The structure of your pattern collection is totally up to you. If you like Brad's atom/molecule/organism thing, go for it.
- The plugin creates an automatic pattern collection at something like
https://yoursite.com/patternlabwith all the patterns in your patterns folder.
- You use the patterns you create in your Kirby templates and snippets to build your site.
The anatomy of a pattern
This is the template file, which contains the HTML code for your pattern. It inherits all the stuff you are used to from building templates and snippets in Kirby. You can access all the pages, files, site object, etc.
With the optional defaults file you can define the default values for variables, you will use in your pattern. I will get to that in a minute.
Using a pattern
To use a pattern in your Kirby templates or snippets, you can simply call the
pattern() function and pass the path of the pattern plus the data for it. It works pretty much like snippets in Kirby.
<?= pattern('atoms/button', ['label' => 'Click me!']) ?>
As an example, the pattern code in
/patterns/atoms/button/button.html.php would look like this:
<button type="button" class="btn"><?= $label ?></button>
We could now combine this with a
/patterns/atoms/button/button.css file for example to create the design for our button pattern. If you need some js magic for the button, the matching js file could go right next to it. But of course it's all optional.
Working with defaults
We can spice this example up some more with additional default values. By default our button should have the btn class, but this should be overwritable. So we create a
/patterns/atoms/button/button.defaults.php and add the following code:
<?php return [ 'class' => 'btn', 'label' => 'Save' ];
The pattern plugin will now pass those default values to the pattern if they are not overwritten by the pattern function. To overwrite them we can pass them in the data array:
<?= pattern('atoms/button', ['class' => 'btn btn--negative']) ?>
Of course patterns can be nested just like in patternlab:
<!-- patterns/molecules/searchform/searchform.html.php --> <form class="searchform"> <?= pattern('atoms/input', ['placeholder' => 'Search…']) ?> <?= pattern('atoms/button', ['label' => 'Search']) ?> </form>
Designing with real content
Here's where it gets really cool. With Kirby there's the chance to actually pull in real content for our patterns directly from your site. Since our patterns have access to pages, files, etc. we can use them as default values and to extend our patterns even further.
The patternlab app
With all your patterns in place, the pattern plugin automatically creates a dynamic presentation of your patterns at
https://yoursite.com/patternlab or a different path you specifiy in your config. You get an overview of all available patterns and you can check them out individually. Each pattern gets its own URL, defined by the folder structure in your patterns folder.
Build process agnostic
Into the wild
Before I wanted to make anything about this public, I wanted to see how practical this really is. I'm currently working on a larger client project and sat down to convert the already existing frontend to the pattern version. It took me about half a day and turned out to work really really well. That's why I'm quite optimistic that it will become my personal standard for future projects.
I'm personally not using Brad's atom/molecule/organism structure and prefer a more semantic approach. But that's just a detail. You can see my current patterns folder for the project here.
My experience so far is that it really helps to modularize your frontend code. Since you live inside the patterns folder, there's not even a single second you have to worry about any additional overhead to maintain this. It's just where you build stuff now and this is great.
One of the most valuable opportunities for me personally has become the option to play with the default values in order to test my designs. For this particular project I had to build a project page with massively varying text lengths and image formats. In order to be able to test this better, I created a project pattern with lots of sub patterns for the different parts of the project page. In my project template the pattern gets filled with the project the user currently browses, but with the help of default values, I'm shuffling the currently active project for my patternlab version. The defaults file for the project pattern looks like this:
<?php return [ 'project' => page('projects')->children()->visible()->shuffle()->first() ];
In my template I use the pattern like this to overwrite the random default project with the current page:
<?= pattern('project', ['project' => $page]) ?>
But when I go to
http://myproject.com/patternlab/project I get a different project pulled in every time I refresh the browser window. So I can just sit down and refresh a couple of times to test how well the content works with the design I created. This is really really helpful.
This is alpha and not publicly available yet. But I plan to release it as soon as there's a little more progress on the automatic presentation of patterns.
While building it I also thought about combining it with an extensive dummy data plugin. By providing simple ways to create all kinds of text blocks and strings, as well as placeholder images, the default values for patterns would become a killer way to use this as a prototyping tool at the same time.
I'm very excited about this. Not only as a valuable addition to Kirby, but as an improvement for my own workflow for client projects.
I'm super interested to hear what you think about it. Just shoot any ideas at me on Twitter: https://twitter.com/bastianallgeier