Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
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.
Data file structureExample of different component states
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 pattern 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 + SSMACSS + 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 Shadow 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.yourName objectBehavior example
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:
Example of correct codeâââtwigExample of correct codeâââyml
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:
Inputâââexample of incorrect code
Guess what? This is wrong. Drupal uses Attribute object for the forms and form controls to set and manipulate their HTML attributes.
Learn about Attribute object and best practices how to use it here
So the correct way is something like this:
Inputâââexample of correct code
Luckily to make it work in Pattern Lab(thanks again to Data Transform Plugin) we can emulate attributes object inside a data file:
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
learn about kint and locating of Drupal templates
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:
â Particle
â Emulsify.
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:
Menu to open component in a separate window
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:
- aleksip.net
- phase2/particle
- Emulsify // Pattern Lab + Drupal 8
- Join Drupaltwig on Slack!
- Blog & Digitale News | BUZZWOO!
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.
Front end journey into Drupal + Pattern Lab was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.