Pattern Lab is a hot topic in Drupal community nowadays, it offers a lot of perks and it promises easy life for designers, clients and finally for developers. Being modern and innovative our team surely couldn’t pass by so we watched and read several articles about and full of excitement brought it to the upcoming project. One thing I noted though was that most part of the presenters had significant knowledge of Drupal which wasn’t my case but I didn’t pay attention that time.
There are 3 reasons we liked Pattern Lab for and I will go through them sharing what we found out and which you should pay attention on while adopting the technology.:
- Component based approach
- Decoupling frontend and backend so frontend can work without knowing the guts of Drupal
- Nice pattern library playground which can be shown to the customer/designer for early review
1. Component based approach
With rising of frontend frameworks like React, Angular 2+, Polymer and many others it is hard to imaging non-component based front end architecture nowadays which in short means that every component has its own scope for data, view and controller logic, which are normally presented with JS, CSS and JSON or YML, meaning changes inside one component won’t affect styles and internal logic of others.
So the normal component looks like this:
Pattern Lab recommends to group assets into folders based on Atomic design methodology and provides a great support for component’s isolated dummy data giving us freedom to choose our own tools to handle JS and CSS scope which is a clever move in the sense that they cannot predict the preferred stack we normally use for that.
HTML: there is no much of complications about HTML scope so we just create own
twig template for each component and then use it wherever we want through include and embed twig directives passing appropriate parameter values.
Component Data: we can choose JSON or YAML format for components dummy data. Both are great and there are easy ways to quickly migrate from one to another though we picked YAML as it looks cleaner:
These files are used solely to render components in the Pattern Lab UI and never appears on production. We can set multiple instances of dummy data for each component by simply altering the file name postfix separated with the tilde symbol which makes it super useful for testing and demonstrating different states of the component.
There is a global data file which is accessible throughout the tree of components so it is good idea to put for example global menu items or footer links there. Global data file is normally accessible by this location:
pattern-lab/source/_data/data.yml.
Caution: The only data that is used to render a component is its own data and global data. If we include or embed component_1 inside component_2 we have to put data for component_1 into the data file of component_2. If you want to avoid that manual work check out this plugin: Data Inheritance Plugin.
CSS: we used SCSS + SMACSS + BEM combination which gave us a way to isolate CSS through class naming convention. I won’t go into details here but you can take a look on some SCSS tricks to achieve this. I’m also looking forward into CSS Modules for future projects.
JS: is the most complicated part and breaks into several tasks.
Module bundler: Drupal 8 by default provide a very cool way to attach component’s CSS and JS to the page by introducing a library concept which allows to specify different bundles in Drupal config and then include only those of them into the page which are really required. A library definition can look like this:
And then has to be attached to the template by any of the methods described in documentation here.
The problem can rise if
accordion.js from our example has its own dependency inside. It’s not a good idea just to put this dependency on the same level in config file cause in this case we have to copy it over everywhere. And if there are several levels of dependencies things become very confusing.
To solve this we used good old Browserify, and Webpack can also be an option. To make it work we just
require module inside our JS file and let Browserify handle it for us through a
gulp task. That’s how our
overlay component javascript file begins:
Another issue is that Pattern Lab knows nothing about the Drupal libraries concept and if we want our components to work inside its sandbox we have to add all same libraries into the
pattern-lab/source/_meta/_01-foot.twig file to make sure our JS is accessible on all pages inside the testing environment.
To simplify things in the beginning we just created one big JS bundle and attached it both to Drupal and Pattern Lab. Luckily we were able to keep the bundle relatively small and there were no much room to split JS between pages so our temporary solution became permanent :)
Component interaction: Once we have all components isolated we have to define a way how they communicate to each other.
Imagine we have a header component and a sidebar menu which slides-in any time button is pressed in the header.
We could do the logic right inside the header JS(inside a click event handler) but as soon as we strived to a loosely coupled architecture we decided to go with a simple mediator pattern in place and choose Redux. It’s a pretty popular one and I covered some of its aspects before.
One issue to not forget is that Redux by default calls all
store subscribers which we don’t want to happen cause we don’t have Virtual DOM and clever change detection mechanism here like React has, so we used an extension called
redux-watch and wrapped our
subscribe method in the way that only required
reducer is invoked:
If terminology sounds confusing Redux documentation may be helpful.
Drupal behaviors: If you never worked in Drupal projects you have to make yourself familiar with Drupal Behavior concept. In short in Drupal world we cannot rely on any document load events because any time Drupal through AJAX can replace any part of HTML with the fresh version of it and the only way we know about that is through
attachBehaviors method call.
So rule of thumb here:
Always wrap your JS code with
Drupal.behaviors.yourNameobject
Though Pattern Lab knows nothing about
behaviors and we have to manually attach
drupal.js from Drupal core to all of our Pattern Lab pages inside
pattern-lab/source/_meta/_01-foot.twig file:
Together with
ready.js. This is already included in Emulsify Drupal theme which I will cover later so probably you just need to uncomment appropriate lines of code.
Taking everything above is done and working seems we are good to go.
But wait!
2. Decoupling
One of the important aspects of Drupal + Pattern Lab combination is decoupling frontend work from backend meaning that those two teams can work almost independently by having clear separation defined by list of components and their parameters. And here tricky things begin.
Decoupling is achieved by twig namespaces module which gives a way to put all frontend templates in one place and then reference them from Drupal templates folder.
Still sounds good overall.
Forms: So let’s start with the forms. If you think you can make an input component and then in a Pattern Lab template
include it inside a form like this :
you are wrong.
The way Drupal handles it is first it renders separately each input component as a
field and then provide this rendered HTML as a string parameter to the
form. First time we found that out, we created an
if clause where for Pattern Lab we used
include and for Drupal we used rendered field . We created a global parameter named
patternLab in
pattern-lab/source/_data/data.yml file to have a way to distinguish if we are inside Pattern Lab or not.
Don’t do this.
First you cannot be sure there is no
patternLab variable in Drupal and second there is a cleaner way to do the same which allows to have single version of
twig file by moving Pattern Lab data to the place where it is supposed to be, to the YAML file:
This is achievable thanks to Data Transform Plugin by aleksip(very cool guy!, follow him if you are into Drupal front end).
Attribute object: My first implementation of input looked like this:
Guess what? This is wrong. Drupal uses
Attribute object for the forms and form controls to set and manipulate their HTML attributes.
Attributeobject and best practices how to use it here
So the correct way is something like this:
Luckily to make it work in Pattern Lab(thanks again to Data Transform Plugin) we can emulate attributes object inside a data file:
Update 19.01.2018: There is a cleaner way to handle attributes in Pattern Lab. Please check out the superb response from Evan Willhite, maintainer of Emulsify here.
But
Don’t use
create_attribute()method inside Pattern Lab. It is not supported. You should only use it in the Drupal templates folder.
Modules: Drupal allows to quickly build a web application thanks to huge amount of contributed modules.
I am not sure why(may be some modules are not fully migrated to Drupal 8 or it is simply difficult to separate a view for them) but there are cases where you have to deal with whatever HTML you get from the server if you want to keep your fast development pace fast. One of the examples is a search results. If you prepared a template for that you can throw it away. The only way you can style it is overriding CSS for that HTML which is already provided by the module.
Define with your team all modules to be used in the project in advance
Forms, validation messages, shariff, sitemap are good candidates for that. There was a case where I had to ask Drupal team to add a class to the element so I can add a padding in the end. Like it or not we have to deal with it.
Sometimes a module may be picked based on the underlying JS technology. Very popular Simple hierarchical select for example uses Backbonejs inside so be ready to learn it on the way to debug your application.. or ask team to consider alternative one.
Responsive images: Separate attention to Drupal Responsive Images module cause there are high chances it will be used in the application.
Be ready to receive from the server the whole rendered <picture> element instead of image path in your templates.
Translations: Not very Drupal-specific but remember about translations in your twigs. Discuss with the team which of those you’re going to use:
string | t or
{% trans %} string {% endtrans %}
and don’t forget about translation context if it is required though it can be fixed later with replace-all IDE functionality.
Debug Drupal: It is forbidden to write about Drupal debugging in the chapter dedicated to decoupling frontend with backend but
We front end developers may not use these methods ourselves but at least we should know they exist and ask Drupal team to help with debugging when needed.
Themes: Drupal is a big open-source community meaning many things are already in place and done by some clever guys. To avoid reinventing the wheel it is good idea to start with the Drupal theme which already includes Pattern Lab. The most popular are:
We started with Emulsify and I very appreciate the way they organized the
gulp tasks and documentation but be careful as they use Pattern Lab Standard Edition for Twig by default which doesn’t include important Drupal plugins namely:
— Drupal Twig Components plugin which allows to use Drupal filters and functions in Pattern Lab(say
| t filter)
and already mentioned above
— Data Transform plugin which makes life much much easier(
Attributes object,
include inside YML files, etc.)
Particle theme at the same time uses Pattern Lab Twig Standard Edition for Drupal which includes both mentioned plugins by default and some useful methods like
npm run new.
Choose the correct Pattern Lab edition.
If you still prefer the way everything organized in Emulsify theme just update
pattern_lab.sh file in it to pick the right edition.
3. Pattern Lab UI
Pattern Lab UI is good and easy to use. It allows to view a specific component, group of components or search one if you are not sure how to access it from the menu.
One thing you probably should remember is that
all your controls are tested inside an iframe
If issues or special case arises(print page feature, for example) there is a way to test the component in a separate window outside of iframe:
Pattern Lab UI has a lot of settings but I didn’t find any good documentation for them. Please share in comments if you know one.
Who to follow
There are couple of blogs/repos I would suggest to follow to get some insights:
The personal website of Aleksi Peebles, a professional web developer since 1996 and a Drupal developer since 2007.
particle - A starting place for using the prototyping tool, Pattern Lab, in tandem with a Drupal theme. Can be used…github.com
Components are the reusable chunks of web sites. They can be small (inputs, labels, buttons), medium (header, footer…emulsify.info
Emulsify theme maintainer’s Evan Willhite blog:
Evan Willhite is a senior frontend engineer at Four Kitchens with who thrives on creating delightful digital…
Willkommen im Blog der Internetagentur BUZZWOO! Hier finden Sie Artikel zu folgenden Themen: Drupal ✓ Wordpress …
And other resources suggested in the responses below(here).
Conclusion
Pattern Lab indeed is a very nice way to organize and present front end template library and I don’t know any good alternatives for achieving that at the moment taking it is not a headless Drupal project.
Projects like Particle and Emulsify make a strong move towards decoupling the front end and back end work though it is naive to think that having a prior Drupal experience is not a requirement anymore to write high quality front end code in such projects. Knowing how Drupal theming, forms and other popular modules work is still indispensable in my opinion.
Have fun with coding and please let me know about your experience in the comments.