Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

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.

The solution

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 Alpha

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/patternlab with 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

Each pattern can have stylesheets, javascript files, fonts, images, etc. Additionally you can provide two files for Kirby:

{pattername}.html.php

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.

{pattername}.defaults.php

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']) ?>

Nesting patterns

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.

For example https://yoursite.com/patternlab/atoms/button displays your button pattern with all the connected files. It will prefill the pattern with the defaults you defined, will show you the HTML of the pattern, the PHP code for your pattern, the stylesheet, the javascript file and an optional description, which can be stored in markdown right in the pattern folder.

Build process agnostic

The plugin does not give you any build tools or force you into a specific build process. In my current version, I'm using a simple Gulp setup to process, combine and compress all the sass files and javascript for my patterns. But of course you are free to use npm or grunt or whatever you prefer to create the final assets for your site.

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.

Patterns

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.

Plans

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.

Feedback

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

@bastianallgeier

This comment has been minimized.

Copy link
Owner Author

@bastianallgeier bastianallgeier commented Jan 22, 2016

First screenshots of the styleguide backend:

screen shot 2016-01-22 at 18 14 04
screen shot 2016-01-22 at 18 14 13
screen shot 2016-01-22 at 18 14 22
screen shot 2016-01-22 at 18 14 34
screen shot 2016-01-22 at 18 14 44
screen shot 2016-01-22 at 18 15 00

@bastianallgeier

This comment has been minimized.

Copy link
Owner Author

@bastianallgeier bastianallgeier commented Jan 22, 2016

And here's one more screenshot of the built-in Markdown parser.

screen shot 2016-01-22 at 19 02 07

@maxfenton

This comment has been minimized.

Copy link

@maxfenton maxfenton commented Jun 8, 2016

Want.

@Thiousi

This comment has been minimized.

Copy link

@Thiousi Thiousi commented Jun 17, 2016

That's looking great !!

@rafegoldberg

This comment has been minimized.

Copy link

@rafegoldberg rafegoldberg commented Jan 17, 2017

this is an awesome idea

@crealistiques

This comment has been minimized.

Copy link

@crealistiques crealistiques commented Mar 19, 2019

I'm really interested in this stuff! Sounds great and definitely a way to go imho.

Is there any progress?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.