Jun 01 2018
Jun 01

Let's have a quick look through our development process on this project and pick out some of the more interesting bits. As briefly mentioned in the last article we are using a composer set up and all code is version controlled using git on github. All pretty standard stuff.

Frontend

In the previous article I briefly discussed how we set up Pattern Lab. Before getting stuck in to the components that would make up the pages of the site, we first needed to set up some global variables and grid. Variables allow us to reuse common values throughout the SCSS and if we need to make a change we can do so centrally. After adding variables for each of the colours and also a colour palette mapping which would allow to loop through all colours if we needed to throughout the project, we added variables for padding that would be used throughout and also font styles, after importing from Google Fonts.

CSS Grid

Although still relatively new, CSS Grid is a web standard and works in all modern browsers. So much simpler than using grid libraries like Susy we were keen to start using it on our projects and this was the perfect one on which to try it out. Set up was simple, partly due to the simple grid in the designs but mostly due to the simplicity of CSS Grid itself. A few lines of SCSS and the grid wrapper was set up:

.grid {
  display: grid;
  grid-auto-rows: auto;
  grid-gap: 20px;
  grid-column-gap: 20px;
  grid-template-rows: minmax(0, auto);
}

This declares the grid, sets a consistent gap of 20px and sets a broad size range for the rows. As well as adding the .grid class to the wrapper of where we'd like a grid, we also need to add another class to define how many columns that grid should have. Defining, in SCSS, a simple mapping allowed me to create a loop to generate the column classes we needed:

// Column mapping
$columns: (
  one: 1,
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
);

// Generate column classes
@each $alpha, $numeric in $columns {
  .grid--columns-#{$numeric} {
    grid-template-columns: repeat(#{$numeric}, 1fr);

    @include to-large {
      grid-template-columns: repeat(1, 1fr);
    }
  }
}

This loop generates a class for each of the potential number of columns we might need. The last @include in the above code simply resets the column definition, making all columns full width on smaller screens. Now, all we needed to do was add 2 classes and we'd have a grid!

Occasionally, we'd have a need for grid items to to span more than one column. Using the same mapping as before, I created a simple loop that would generate classes to define different column spans. These classes could then be applied to the immediate children of the grid wrapper.

.grid__item {
  @include from-large {
    @each $alpha, $numeric in $columns {
      &--span-#{$alpha} {
        grid-column: auto / span #{$numeric};
      }
    }
  }
}

Now we have complete control over our grid. Here's a example of how it's used.

<div class="grid grid--columns-6">
  <div class="grid__item">
    First item
  </div>
  <div class="grid__item grid__item--span-two">
    Second item spanning two columns
  </div>
  <div class="grid__item grid__item--span-three">
    Third item spanning three columns
  </div>
</div>
Pattern Lab

In the previous article I mentioned the setup of Pattern Lab and Emulsify but didn't look in to the actual development, so let's do that now! Although we're used to coding SCSS in a modular way here at CM, with Pattern Lab's stand alone components essentially working like modules we actually don't need to take too much care to produce nice clean code. Each SCSS file is only catering for a small component on the page and as such is usually small and specific.

But, as well as including our pattern specific code within each component's directory we needed to ensure that we also considered working in a SMACSSy way to reduce the CSS we were generating. We didn't want multiple classes applying the same styling, so any rules that would be reused and consistent, like padding, were placed inside the Base folder in a Base SCSS file.

Of course, once we had defined our classes we needed to get them in to the Pattern Lab Twig templates. As components will have variations we can't just hard code the classes in to the templates, we need to pass them in as variables. Passing variables to Twig files is super simple and with Emulsify 2.x there's now even Drupal Attributes support with the addition of the BEM Twig extension. As we are likely wanting to pass multiple classes to the same element we can pass in a simple array of modifiers and render it out in the Twig template. So in a Drupal preprocess we can prepare some modifiers (we'll look at passing these on to the Pattern Lab Twig files later):

$variables['heading_modifiers'] = ['centered', 'no-space'];

And then in our Twig file we pass this through the BEM function:

{% set heading_base_class = heading_base_class|default('h' ~ heading_level) %}
<h{{ heading_level }} {{ bem(heading_base_class, heading_modifiers) }}>
    {{ heading }}
</h{{ heading_level }}>

Which renders the markup as:

<h1 class="h1 h1--centered h1--no-space">
  Heading
</h1>

Backend

The beauty of using Pattern Lab is the ability to work simultaneously on frontend and backend development. Before bringing more hands on deck I was able to begin the backend of the site before getting even close to completing the frontend. As mentioned earlier, the codebase was set up before the Front End work began so we could jump straight in to the Emulsify theme. Using composer allowed us to quickly get Drupal 8 and a bunch of contrib modules we needed so when we were ready to start on the backend we could jump straight in.

This site required nothing too complex in terms of backend development and the work was more a task of building content types and views to display content as per the designs. That said, we did utilise the Paragraphs module allowing us to create reusable entities, or tiles as we're used to calling them, as they are used extensively throughout the designs.

Configuration

Something that hasn't been standard in our Drupal 8 builds since the release is configuration. Gone are the days of bundling settings in to features, Drupal 8 Core comes with configuration management tools. In the early days, one of our senior developers created cm_config_tools - a module to give developers precise control over what config to export. Drupal 8 has progressed since then and the timing of this project allowed us to use a new module, Configuration Split.

Configuration Split builds on Drupal Core's configuration management ability to export a whole set of a site's configuration by allowing us to define sets of configuration to be exported to separate directories. It's then possible to define in settings.php which directories to include when importing/exporting. As we were committing settings.php to git we could include the main config directory here and then have a local.settings.php (not committed to git) to define the database and any other config directories to include:

## Enable config split settings
$config['config_split.config_split.local_dev']['status'] = TRUE;
$config['config_split.config_split.local_overrides']['status'] = TRUE;

This means we can have configuration solely for use when developing (things like Devel and Field_UI). It's also possible to override settings that are included in the main config export, locally. This allows us to run local environments without fear of interfering with live functionality, like affecting comments by changing the Disqus Domain, for example.

Importing and exporting works the same way as Core's configuration management, by using Drush commands:

Drush cim
Drush cex

Templating

In a normal Drupal project, the markup (Twig files) would be within Drupal's templating system with prepared variables being rendered out where they were needed to be. With our component based Pattern Lab, all of our markup was within the Patten Lab structure, away from Drupal's /templates directory. Fortunately, including them is simple enough. First we needed to download and install the Components Libraries module. This allowed us to specify a different directory for our Twig files and also register Twig namespaces for those files. We do this in the theme's .info file:

component-libraries:
  base:
    paths:
      - components/_patterns/00-base
  atoms:
    paths:
      - components/_patterns/01-atoms
  molecules:
    paths:
      - components/_patterns/02-molecules
  organisms:
    paths:
      - components/_patterns/03-organisms
  templates:
    paths:
      - components/_patterns/04-templates
  pages:
    paths:
      - components/_patterns/05-pages

Now our Pattern Lab Twig files were included, we could begin to link them up to Drupal's templating system. Linking them is as simple as choosing which components you want to display and then calling that Twig file from your Drupal template. When you call the component's Twig file you just need to pass in the variables from Drupal.

So if we wanted to display a page title as an H1, within page-title.html.twig inside Drupal's template directory we would call our Pattern Lab's heading component passing in the title and heading level:

{{ title_prefix }}
    {% if title %}
        {% include "@atoms/02-text/00-headings/_heading.twig"
            with {
                "heading": title,
                "heading_level": 1,
            }
        %}
    {% endif %}
{{ title_suffix }}

If we wanted to change the style of the heading we could pass in an array of modifiers, as shown in the example further up the page, too. For more complex page components we can also pass in an array to be looped over inside the component's Twig file. For example, if we wanted a listing of cards we could pass an array to a listing component Twig template and within that loop through the array each time calling another component's Twig template:

<div class="grid grid--columns-3">
  {% for item in content_array %}
    <div class="grid__item grid__item--{% if loop.index is divisibleby(2) %}right{% else %}left{% endif %}">
      {% include "@molecules/card/01-card.twig"
        with {
          "card_img_src": item.image,
          "card_title": item.title,
          "card_body": item.body,
          "card_button_content": item.button_text,
          "card_button_url": item.button_url,
          "card_button_modifiers": item.button_mods,
          "card_url": item.url,
          "card_img_alt": item.image_alt,
        }
      %}
    </div>
  {% endfor %}
</div>

This is just a brief overview and a look at some interesting parts, there was obviously a lot more work that went in to the site build! Now, as this website was being built to replace our old site, we needed the content from old site to be moved over. In the next article Christian is going to talk through this process.

May 03 2018
May 03

We didn’t see this project solely as a chance to rebrand and rebuild for ourselves, it was also an opportunity to try something new and expand our collective knowledge with the potential for using with clients in the future. We had been discussing using Pattern Lab for Front End development for some time and this was the perfect opportunity to try it out.

Patten Lab allows the creation of component-driven user interfaces using atomic design principles. This means we can create modular patterns all packaged up nicely that can be assembled together to build a site. Plus we can use dynamic data to display the patterns in a live style guide which makes viewing each component quick and easy. And nobody is viewing out of date designs or code - an issue we had on a recent project. With Pattern Lab, we would have a central place to view all of the actual components that will be used on the live site.

The guys over at Four Kitchens made implementing a Pattern Lab with Drupal super easy, by creating Emulsify. Serving as a Drupal 8 starter kit theme, Emulsify allows you to build and manage components without using Drupal's template names but by using custom template names that make sense to everyone, instead. When you're ready, you can easily connect them up to Drupal.

Building the frontend in this way allows it to be built separately from the backend development. It's possible to create the whole of the front end before even touching Drupal. If needs be, it also allows developers to work on the frontend and backend at the same time without stepping on each other's toes.

Because we were to be using Emulsify, we quickly set up a Drupal codebase (using composer) which allowed us to then jump in and clone the Emulsify theme and begin working on the Front End. Once we had the theme, it was real easy to get the sass and javascript compiling, set up a local server (to view the style guide) and watch for changes, with one command:

npm start

As well as compiling, this command also provides a url for the local server. Open it up in a browser and you can see your live style guide!

Now for the actual components. These are filed in the theme, inside:

components/_patterns/

As we're working with Atomic Principles, the smallest components are filed first building up to the biggest. The beauty of pattern lab is nesting - it's possible to include patterns inside each other to make larger components. Although it's not necessary to use Atomic Design naming conventions when organising patterns, it does make sense. These levels are:

  1. Atoms
  2. Molecules
  3. Organisms
  4. Templates
  5. Pages

Atoms are the basic elements of the site like HTML tags and buttons. Molecules combine these Atoms to create larger components like a card and then Organisms can combine Molecules to create more complex page components and so on...

Numerics are added to ensure they are listed in the correct order and also a Base folder is added to house variables, breakpoints, layouts and global sass mixins. So, this is how our file structure looks inside that _patterns folder:

- _patterns/
    - 00-base
    - 01-atoms
    - 02-molecules
    - 03-organisms
    - 04-templates
    - 05-pages

Within each of the Atomic Design folders is a set of components. Each component comprises of a Twig file, a Sass file and in some cases a Javascript file. These files contain code specific to that component. Having all the code for each component organised this way makes it really easy and fast to edit components, and also add new ones.

Having just the code that makes the component isn't enough for us to view it in our style guide. In addition to the files that make up the component, we can also include files to give the component context. A Markdown file allows us to give the component a title and description, which are used in the navigation and style guide. To each component folder we can also add a YML file which holds filler content solely for use for the style guide. We basically just take each variable name from the twig file and provide some content for each.

So, a typical component file structure might look like this:

 - card
    - _card.scss
    - card.md
    - card.yml
    - card.js

Once we had a full understanding of the structure and had added our colour palette and set up our grid and breakpoints it was a case of working through the designs to determine what the components were and of which size. Then starting with Atoms and working up we could build each component. We'll look at the actual development in the next article in the series.

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web