Decouple your Pattern Library from your Theme.
sf.gov
I am Israel Morales
and I work in Chapter Three
as Front End Developer
Remotely
:)
Benefits
the same pattern library can be used by other projects.
Requirements:
the use of twig
Usually:
The pattern library lives inside your Drupal theme... most of the time:
Pattern lab drupal themes or starter kits:
A list of features:
Client Requirements!
- We need a Pattern library
- we don't care which one is
- We want to implement uswds (for fast prototyping) but we want our own custom PL
- We want to develop the Pattern lab independently of Drupal, so our developers don't require to have knowledge of Drupal
- We need it fast
uswds
Pros
- Fractal
- not well maintained
- SASS super opinionated
- https://www.bourbon.io
- https://neat.bourbon.io
- no use of flexbox or css grid
- not compatible with twig :(
- lacking of components, mostly basic components were available.
Cons
- Fractal
- easier than PL
- If used as framework can do stuff fast.
USWDS
I actually tried to refactor all the tamplates to twig and I failed miserably :(
I even tried to use many of the Drupal theme solutions...
and then just override with my stuff.... but...
In my mind:
- USWDS should be included as library
- meaning that we will be able to use USWDS classes and JS
- SFGOV PL should be clean from other frameworks/pattern libraries
- SFGOV PL should have a class identifier to avoid class collisions or overlaping so all classes would start with `.sfgov`
- USWDS JS should work along side SFGOV.
So I started fresh.
Steps to decouple your pattern library:
1.- Choosing the breed
there are a lot of options for pattern lab out there but in my case non of them matched my expectations
-
some of them were too opinionated
- some of them were deeply integrated with the Drupal theme.
- So I choose https://github.com/pattern-lab/edition-php-twig-standard
- Other options: https://patternlab.io/docs/installation.html#php
1.- Edition php twig standar means:
means that this edition is bare, with no additions, just the basic stuff.
- composer to install all the required libraries
- core has some PHP scripts for after composer install
- public is were your compiled PL is going to live
- source is were your components and other stuff is going to be.
1.- how to start with the standard edition.
- comes with a watcher and other commands you can use for example:
composer create-project pattern-lab/edition-twig-standard badcamp-2018
1.- Edition php twig standar also means:
- no SASS or SCSS watcher
- no JS compiler
- only PHP watcher and compiler
2.- Add Watchers so, we can compile:
- For this specific project I used Gulp
- But you can use webpack, or whatever tool you can use to compile JS and CSS.
2.1 - For this project I used Gulp
- because I was familiar with it.
- But you can use webpack, or whatever tool you can use to compile JS and CSS.
2.2- Watchers for everything:
// Watchers for everything:
gulp.task('watch', function () {
gulp.watch(config.js.src, ['legacy:js']);
gulp.watch(config.css.src, ['pl:css']);
gulp.watch(config.pattern_lab.src, ['generate:pl']);
gulp.watch(config.pattern_lab.javascript.src, ['generate:pl']);
});
// pl:php
gulp.task('pl:php', shell.task('php pattern-lab/core/console --generate'));
Example of PHP watcher:
2.3- Watcher for SCSS and JS output two single files.
// CSS
/dist/css/components.css
// JS
/dist/pl/js/components.js
3 .- Generate a single CSS and a single JS
so we can use our pattern library as a framework like bootstrap or zurb foundation etc...
3.1 - creating a dist folder with the single CSS and single JS
I committed those files directly to the repo.
But... if you can avoid committing the compiled code and manage the releases with Tag or branches, please do it...
3- Edit Pattern Lab head file.
Editing Pattern Lab head file will include the previously mentioned files, so we can preview our pattern library in the pattern lab PHP server.
// File
/pattern-lab/source/_meta/_00-head.twig
3.1- Edit Pattern Lab head file.
// File
/pattern-lab/source/_meta/_00-head.twig
<!DOCTYPE html>
<html class="{{ htmlClass }}">
<head>
<title>{{ title }}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width"/>
<link rel="stylesheet" href="../../css/pattern-scaffolding.css?{{ cacheBuster }}" media="all"/>
<link rel="stylesheet" href="../../css/components.css" media="all">
<script src="../../js/dist/pl/components.js"></script>
<!-- Begin Pattern Lab (Required for Pattern Lab to run properly) -->
{{ patternLabHead | raw }}
<!-- End Pattern Lab -->
</head>
<body class="{{ bodyClass }}">
4 - creating a Drupal theme
Just create a standard Drupal theme.
5 - Enable the component libraries
The Component Libraries module was especially important because it allowed me to map the Pattern Lab components easily into my theme. Then I had to map my Pattern Lab components with the Drupal theme:
6 - Map your PL to Drupal
Once your Twig templates in your pattern library are working you might want to reference them with the component library and custom Twig namespaces.
6.1 - mapping PL to Drupal
// sfgovpl.info.yml
component-libraries:
protons:
paths:
- ../../../libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/00-protons
atoms:
paths:
- ../../../libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/01-atoms
molecules:
paths:
- ../../../libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/02-molecules
organisms:
paths:
- ../../../libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/03-organisms
templates:
paths:
- ../../../libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/04-templates
pages:
paths:
- ../../../libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/05-pages
libraries:
- sfgovpl/sfgov-pattern-lab
I'm using the ../../../ to reference the libraries forlder in the root of my Drupal install
7 - Using the single CSS and JS via libraries
// sfgovpl.libraries.yml
sfgov-pattern-lab:
css:
base:
'/libraries/sfgov-pattern-lab/dist/css/components.css': {}
js:
'/libraries/sfgov-pattern-lab/dist/pl/js/components.js': {}
// sfgov.info.yml
libraries:
- sfgovpl/sfgov-pattern-lab
- sfgovpl/sfgov-drupal-specific-styles
- sfgovpl/google-fonts
- sfgovpl/resize-disable
- sfgovpl/sfgov-drupal-search
- sfgovpl/fontawesome
8 - Using composer to require our external PL
This plugin allowed me to put the pattern library in a folder different than vendor
Then I added some configuration to the composer.json
I used the following composer plugin:
composer require oomphinc/composer-installers-extender
8.1 - Editing the composer.json
Under extra I specified where composer should install the repository of type github:
"extra": {
"installer-paths": {
"web/libraries/{$name}": ["type:github"],
}
8.2 - Editing the composer.json
Then under repositories I set the type:github
"repositories": {
"github": {
"type": "package",
"package": {
"name": "sf-digital-services/sfgov-pattern-lab",
"version": "master",
"type": "drupal-library",
"source": {
"url": "https://github.com/SFDigitalServices/sfgov-pattern-lab.git",
"type": "git",
"reference": "master"
}
}
}
}
8.3 - Editing the composer.json
and required the package under require: As you can see the name matches the name in the previously declared github repo:
A composer update should clone the github repo and place the Pattern Lab inside relative to the Drupal web folder:
/web/libraries/sfgov-pattern-lab
"require": {
"sf-digital-services/sfgov-pattern-lab": "dev-master",
}
9 - Using the PL templates with Drupal.
// node--topic--search-index.html.twig
<div class="topic-search-result">
<div class="topic-search-result--container">
<div class="content-type">
<i class="sfgov-icon-filefilled"></i>
<span>{{ content_type }}</span>
</div>
<a class="title-url" href="{{ url }}"><h4>{{ title }}</h4></a>
<p class="body">{{ body|striptags('<a>')|raw }}</p>
</div>
</div>
9.1 - Using the PL templates with Drupal.
{# Set variables to use in the component. #}
{% set url = path('entity.node.canonical', {'node': elements['#node'].id() }) %}
{% set description = node.get('field_description').getValue()[0]['value'] %}
{% set type = node.type.entity.label %} {# content type #}
{# Icluding the molecule in our Pattern Lab.#}
{% include "@molecules/08-search-results/03-topic-search-result.twig" with {
"content_type": type,
"url": url,
"title": elements['#node'].get('title').getString(),
"body": description
} %}
Drupal template:
The following example calls the Pattern lab molecule originally located at:
web/libraries/sfgov-pattern-lab/pattern-lab/source/_patterns/02-molecules/08-search-results/03-topic-search-result.twig
but Instead we use:
@molecules/08-search-results/03-topic-search-result.twig
10 - Profit
11 - QA
12 - Thank you
Decouple your Pattern Library from your Theme.
By Israel Morales
Decouple your Pattern Library from your Theme.
- 872