Multi-Design Systems with Component Libraries Module
Multi-Design Systems with Component Libraries Module
J. Ryan Conklin | Developer
March 18, 2019
The Rundown
At Phase2 we’re always looking to pinpoint the real problem and solve it. Let’s say we have a new project to implement a design system for The First Order. We’ve done work for their parent organization in the past and already have a design system in place for The Empire. The site architecture calls for creating a multi-site and multi-design implementation to make use of The Empire’s assets for The First Order.
Particle is Phase2’s approach to Frontend.
It’s a huge starter kit for kick-starting projects with solid JavaScript best practices and ships with apps for Pattern Lab as well as Drupal and Grav themes. Particle allows us to have a jumping off point to get to solving client problems quickly and is designed to work out-of-the-box with a combination of PHP+JavaScript with Twig Templating.
Twig is a powerful PHP templating language, and while we could load all components from relative directories, that doesn’t make sense in terms of code maintainability and extensibility. Writing our new First Order design system to reference the Empire with a series of relative paths would get unwieldy very quickly. Fortunately, Twig allows the use of Twig Namespaces to address this issue. A Twig Namespace is simply a shortcut to a template directory.
In Drupal, to achieve this functionality, we use the Component Library module, while in Grav we use the Twig Namespaces plugin. This allows us to register our Twig Namespaces within the context of the individual app implementation while using Particle’s JavaScript to determine what these paths are.
At Phase2 we really love Brad Frost’s Atomic Design principles and Particle uses these to organize our components out-of-the-box. Pattern Lab is the default app we use to demonstrate these atomic components. Particle’s configuration allows us to have a classic Peanut Butter + Jelly relationship with our components automatically being registered and consumed by our apps using atoms, molecules and organisms as our Twig Namespaced paths. Great! Now we can get to work solving The First Order’s problems.
The Problem
Not so fast though! Twig Namespaces have to be unique. So what happens when you need to provide a multi-design solution? Consider our use case where we have a multi-site platform that requires similar, but slightly different, components in your design?
The First Order really wants to use elements established in The Empire design but they have their own requirements (as well as a few very vocal stakeholders).
In Drupal, we chose a multi-theme build with “The Empire” parent theme and “The First Order” subtheme. Each theme now registers their own atoms, molecules and organisms in empire.theme and first_order.theme. However we’ve hit a snag!
Since Twig Namespaces are unique, the last-in-line namespace will overwrite the previous namespace in the Component Library module. Because the First Order theme includes their own atomic components (atoms, molecules and organisms), these Twig Namespaces override the atomic components declared in the parent theme. Say goodbye to The Empire’s precious and much-used organisms/card--vader.twig
variant.
While there are a few ways to address this problem, the root cause is the Twig Namespaces themselves. In a multi-design scenario adhering to Atomic Design principles, it might be better to prefix the Twig Namespaces with our app name.
Introducing Namespace Prefixing in Component Library
The alpha2 build of the Component Library module now includes the option to prefix a namespace. Addressing this in the Component Library module fixes the issue and provides a solution for The First Order and the community. To try the alpha version out, you can download the Component Library module into your module folder either by cloning the repository or installing via Composer:
Git
git clone --branch 8.x-1.1-alpha2 https://git.drupal.org/project/components.git
Composer
composer require 'drupal/components:^1.1'
This version of the module provides a default config for Namespace Prefixing (off by default). When enabled, the Twig Namespace is prefixed with the theme or module name. In our theme example above, Drupal now sees our Twig Namespaces as empire_organisms/card--vader.twig
. Great! Now The First Order and the Empire can easily share design assets but have their own implementations!
To enable this you can either do so via config (update your sites components.settings.yml) or visit yoursite.com/admin/config/components/settings to enable via the admin interface. We have intentionally left this off the configuration options for the module as it can easily break your site without updating your theme.
Enabling this configuration should be done along with updating your theme’s invoked Twig Namespaces in templates. For example, if your Drupal theme’s page.html.twig contains {% include @organisms/card.twig %}
, you will need to update it to {% include @theme-name_organisms/card.twig %}
or else Drupal will no longer interpret the updated Twig Namespace path correctly.
The development roadmap for Particle has multi-design support next in line and we’re very excited to bring these solutions to a galaxy slightly closer to home.