Atomic Design in Drupal 8:
Isolating Your Frontend Workflow with Pattern Lab!

anthonysimone.github.com/drupal-8-pattern-lab-talk

Welcome to DrupalCon Baltimore! I work for Elevated Third, a digital agency based in Denver, Colorado.

Goals

  • Introduce concepts required for using Drupal 8 and Pattern Lab together
  • Review a practical implementation that can get you up and running immediately
  • Discuss some benefits/challenges of a decoupled frontend workflow in Drupal projects

Atomic Design

  • Create a system of components
  • Use small pieces (atoms) to build out larger elements (molecules/organism)
  • Repeat → components, templates, pages, etc...

Reusable Components

  • Atomic Design dictates creating and implementing reusable, explicitly defined components

Component Patterns in Drupal

  • Fields and field formatters
  • Entities and view modes
  • Paragraphs module

Front End Workflow in Drupal 7/8

  • Sitebuilding → Content → Theming
  • Theming depends on (placeholder) content during development
  • Theming occurs within the entire Drupal context
  • Issues?

Enter Pattern Lab

At its core, Pattern Lab is a static site generator (powered by either PHP or Node) that stitches together UI components. But there's a whole lot more to it than that!

Pattern Lab as a Design System

  • Build pattern driven user interfaces using atomic design principles
  • Create components from consistent, explicitly defined building blocks
  • Documentation - consistent language throughout entire team
  • Pattern Lab Demo Project

Pattern Lab as an Implementation

  • PHP or node version
  • Tool/Language agnostic
  • Templating engine flexible (Mustache, Twig, Handlebars, etc)
  • Extra tools - viewport sizer, annotations, pattern lineage, and more!

How it Works

  • Create smallest templates, include those in larger templates, etc...
  • Templates are backed by a JSON file that provides the data
  • Single source of truth
  • Pull down/check out demo project

Pattern Lab Structure

The Gold Standard

Maintain a Drupal 8 project that implements Pattern Lab. All assets (templates, CSS, JS) are shared between the two projects in an identical state (one source).

Pattern Lab in Drupal (7)

  • Pattern Lab in a Drupal 7 project would require maintaining a two separate projects
  • Using same CSS/JS files would require manually maintaining the consistency between the two projects (woof)

Pattern Lab in Drupal (8)

  • Twig is a templating engine that adds common templating patterns to PHP projects
  • All templates in Drupal 8 are .twig files
  • Integrating Pattern Lab directly into your Drupal project is now a possibility

Challenges Adding Pattern Lab to a Drupal 8 Project

Vanilla Pattern Lab Project

  • Pattern Lab implements the templating language chosen without assumptions
  • Includes and extends build out project structure

For Example


<article class="product">
  <div class="main">
    {% include "atoms-title" %}
    {% include "atoms-landscape-16x9" %}
    {% include "atoms-body" %}
  </div>
  <aside class="details">
    {% include "molecules-details" %}
  </aside>
</article>
						

If you're thinking: "Wait, but that's no good!", you're right, it's not!

Let's Fix It!!

  • ...but, that seems kind of hard.
  • {% include "atoms-title" %} != {{ content.field_title }}
  • Fortunately, some awesome people have already been thinking about the hard problems

Data Transform Plugin

  • Aleksi Peebles developed a solution
  • .twig templates and .json files exist in pairs
  • Leverages .json data to include templates

Special JSON Keys

  • Attribute() - Compiles the Drupal attributes object
  • include() - Include a template in the specified variable
  • join() - Join multiple templates together in the specified variable
  • Allows simple inclusion of templates in {{ content.field_name }} or {{ content }} vars

Attribute()

.json
"attributes": {
  "Attribute()": {
    "class": ["class-name"]
  }
}
						
.twig
<article{{ attributes }}>
  {# ...drupal template content... #}
</article>
						

include()

.json
{
  "label": "Jon Doe",
  "content": {
    "field_profile_image": {
      "include()": {
        "pattern": "elements-profile-image"
      }
    }
  }
}
						
.twig
<article>
  {{ label }}
  {{ content.field_profile_image }}
</article>
						

join()

.json
{
  "page": {
    "content_bottom": {
      "join()": [
        "elements-efq-featured-event",
        "elements-efq-upcoming-events",
        "elements-efq-past-events"
      ]
    }
  }
}
						
.twig
<div class="page-template">
  {# ... #}
  <div class="region-content-bottom">
    {{ page.content_bottom }}
  </div>
  {# ... #}
</div>
						

Implementation

Progress! But, we still must practically get Drupal and Pattern Lab working together.

Some Examples of Solutions

  • Forum One's talk at Drupal Con New Orleans on Drupal 8 and Pattern Lab
  • Phase Two's talk at Drupal Con New Orleans about design process
  • Aleksi Peebles' Shila theme

Further Challenges

Let's look at some more challenges that come up for an implementation of Pattern Lab in Drupal and see how our approach will solve them

Project Structure

  • Where should Pattern Lab live?
  • How will it work?

Two Twigs

  • Drupal 8 and Pattern Lab both have their own implementation of Twig
  • How is this reconciled, without hacking either project?
  • Let's try to work with what we have
Drupal 8 Twig Pattern Lab Twig
Finds templates anywhere in the Drupal theme Recognizes in specific locations within the PL project
Only recognizes templates ending with .html.twig Any templates ending in .twig
Will not include .twig files PL is inside our Drupal project

Given

Problems

  1. Pattern Lab is not aware of templates outside of its project root
  2. Drupal is aware of all templates inside Pattern Lab
  3. We want a single source of truth for our assets
  4. Template directory should live where you might normally expect to find it

Solution

  • Symlinks!
  • In Pattern Lab, link to any folder in the Drupal project containing necessary templates
  • All templates remain in Drupal structure
  • Caveat: must not link to nested folders

Folder Structure

Template Inclusion

/theme/templates/node/node--news--teaser.html.twig
{% set classes = [
  'node',
  'node--type-' ~ node.bundle|clean_class,
  not node.isPublished() ? 'node--unpublished',
  view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
] %}
<article{{ attributes.addClass(classes) }}>
  <div{{ content_attributes.addClass('node__content') }}>
    {{ content.field_date }}
    {{ content.field_link }}
  </div>
</article>
						

Using Templates in Pattern Lab

.../_pattern/03-nodes/09-news/02-news-teaser.twig
{% extends "node--news--teaser.html.twig" %}
						
.../_pattern/03-nodes/09-news/02-news-teaser.json
{
  ...
  "attributes": {
    "Attribute()": {
      "class": []
    }
  },
  "node": {
    "bundle": "news"
  },
  "view_mode": "teaser",
  "content": {
    "field_link": {
      "include()": {
        "pattern": "elements-field-link"
      }
    },
    "field_date": {
      "include()": {
        "pattern": "elements-field-date",
        "with": {
          "items": [
            {
              "content": ""
            }
          ]
        }
      }
    }
  }
}
						

{{ content }}

  • Twig prints strings
  • However, in Drupal {{ content }} works
  • join() can merge multiple field templates into a string and print them all out with {{ content }}

{{ content.field_name }}

  • include() single templates in each key under content and print them with {{ content.field_name}}
  • Currently, you cannot use both in a template
  • Choose one pattern or the other

Custom Filters and Functions

  • Ensure all custom filters and functions are defined in your Pattern Lab project
  • pattern-lab/source/_twig-components

OMG My Repo is SO MESSY

  • Static site generator
  • Ignore the public dir (compilation target)
  • Create a published directory
  • Gulp/grunt task that copies public to published

Check Out a Project

  • Youth on Record is a local non-profit that works with music education and the Denver youth
  • Site build in Druapl 8
  • The Pattern Lab implementation

The Gold Standard

Maintain a Drupal 8 project that implements Pattern Lab. All assets (templates, CSS, JS) are shared between the two projects in an identical state (one source).

Conclusions: Benefits and Challenges

I love this, it's so great! Count me in! 🙋

Decoupled Workflow

  • Frontend workflow can be completely decoupled from Drupal
  • Theme outside of Drupal

Flexible Project Workflow

Permits for a frontend to be designed and built out before a sitebuild must be committed to, without "losing" that time

Componentized Structure

Isolates components by responsibility outside of the Drupal context (wrappers, containers, other element classes, etc)

Styleguide

Produces a comprehensive interactive styleguide asset that develops with the project requiring minimal update

Testing (sort of)

Provides an entire set of data for frontend design system that does not depend on the project database

Quick (relatively) visual "regression testing" for complicated components, or items that have many dependencies and moving parts

Communities

Connecting communities! Pattern Lab is an existing tool with a lot of dedicated followers. And with the hard work of a few people, a bridge to connect Drupal with this large existing community has been made. That's pretty cool!

I'm not sure, this sounds terrifying! 🙀

Time

  1. With a reasonable base setup, the time investment to use this workflow should not be that great.
  2. Though, initial learning curve will be present and all members of the team must have buy in.
  3. Medium/large projects or maintained project, it can potentially save much more time than required to implement

More Tools!

  • PHP/Composer
  • Node/gulp
  • Pattern Lab/Data Transform Plugin/JSON
  • Drupal
  • Twig
  • HTML/JS/CSS
  • Confident debugging issues that result from any combination of the above!

Too Many Tools?

  • Workflow
  • Resources
  • Team members
  • Some may argue that this has already become the commonplace description of a frontend developer in many other spaces

End to End Project Workflow

  • How does your company/team work?
  • The potential benefits require buy in from your entire team

Appendix: Resources

Appendix: Steps to include Pattern Lab in Drupal 8

  1. Install Drupal 8 using your desired method
  2. Add Pattern Lab in your theme: composer create-project pattern-lab/edition-drupal-standard
  3. Choose a starter kit option (demo gives some reasonable examples, the other starter kits have helpful examples as well) choose replace
  4. In pattern-lab/config/config.yml set twigAutoescape: false
  5. Adjust assets in header (pattern-lab/source/_meta/_00-head.twig)
  6. Optionally add/update gulp/grunt tasks for asset workflow
  7. Create a drupal-templates folder in pattern-lab/source/_patterns/08-drupal-templates and create symlinks inside to all of your direct template containing folders
  8. Add any additional filters/functions used in your project, make sure to select Merge on PL updates
  9. Generate your pattern lab for the first time
  10. Start adding templates/json in pattern lab that reference your Drupal templates
  11. Theme and generate as you go!

Join Us for Contribution Sprints

Friday, April 28, 2017

First-Time Sprinter Workshop
9:00am - 12:00pm
Room: 307 - 308
Mentored Core Sprint
9:00am - 12:00pm
Room: 301 - 303
General Sprints
9:00am - 6:00pm
Room: 309 - 310

Thank you!

What did you think?

Locate this session at the DrupalCon website

Take the survey!

Questions? Comments? Thoughts?