Using Pattern Lab to template disparate systems

Working in a large corporation with many disconnected systems is a massive challenge when it comes to branding, the systems are all very different, worked on by developers with differing techniques and specialisms. It’s a nightmare.

I recently devised a solution using Pattern Lab, Gulp, CircleCi and some basic PHP web hosting.

A quick breakdown of this solution is as follows:

  1. Build all templates, javascript and css in Pattern Lab
  2. Build those out and upload them to a remote accessible location
  3. Use some basic PHP to expose the available templates and assets
  4. Consume those templates and assets in the other systems and use them for rendering. I have successfully used this in both Drupal and WordPress so far.

Advantages:

  1. Build your components once, use everywhere. No duplication of effort
  2. Maintain a consistent brand between platforms
  3. As users move between systems they’ll be pulling assets from a single location resulting in faster render times thanks to caching

Source for this solution is available on Github

Build your patterns

I used the Node Gulp edition of PatternLab because I’m familiar with Gulp and it’s easy to configure but it’s up to you. Make sure you structure your elements and code sensibly and come up with some coding standards and rules from the get go.

Prepare to sftp

Get yourself some hosting credentials and add them to CircleCI through their web interface, do not store your credentials unencrypted in the gulpfile.js, that’s never a good idea.

Next up add the following to your gulpfile. Tweak as necessary to reference whatever you called your hosting credentials in CircleCI. You’ll also see frequent calls to paths(), this is a method provided by Pattern Lab, it should already be in your gulpfile.js somewhere.

let gulp = require('gulp');
let path = require('path');
let zip = require('gulp-zip');
let sftp = require('gulp-sftp');
let rename = require("gulp-rename");

gulp.task('deploy:zip', function(cb) 
{
  let patternsPath = paths().public.patterns;

  return gulp.src([`${patternsPath}**/*.mustache`])
    .pipe(rename(function (path) {
      path.dirname = '';
    }))
    .pipe(zip('templates.zip'))
    .pipe(gulp.dest(paths().public.root));
});

gulp.task('deploy:sftp', function(cb) 
{
  var PATTERN_HOST = process.env.PATTERN_HOST;
  var PATTERN_PORT = process.env.PATTERN_PORT;
  var PATTERN_USERNAME = process.env.PATTERN_USERNAME;
  var PATTERN_PASSWORD = process.env.PATTERN_PASSWORD;

  var CURRENT_BRANCH = process.env.CIRCLE_BRANCH;
  var BUILD_NUM = process.env.CIRCLE_BUILD_NUM;

  // This check is commented out as it is only availble within CircleCI
  if (CURRENT_BRANCH !== "master") 
  {
    cb("Cannot SFTP from this branch");
    return;
  }

  return gulp
    .src('**/*.*', {cwd: normalizePath(paths().public.root)})
    .pipe(rename(function (path) {
      path.dirname = `${BUILD_NUM}/${path.dirname}`;
    }))
    .pipe(debug({title: 'sftp:'}))
    .pipe(sftp({
      port: PATTERN_PORT,
      host: PATTERN_HOST,
      user: PATTERN_USERNAME,
      pass: PATTERN_PASSWORD,
      remotePath: `/`
    }));
});

gulp.task('deploy', gulp.series('deploy:zip', 'deploy:sftp'));

Setup a basic build process

There’s not much required in terms of build process

machine:
  node:
    version: 6

dependencies:
  override:
    - npm install

database:
  override:
    - echo "Skip."

compile:
  override:
    - npm run build

test:
  override:
    - echo "Skip."

deployment:
  release:
    branch: master
    commands:
      - npm run deploy

Run a build

Enable building for the repository in CircleCI then check your code into the master branch in GitHub and what the build process kick off. With a bit of luck by the end you should have a new directory created on your web hosting containing a pattern zip file, some css and some javascript.

Syndication

It’s up to you how you do this but you’ll need a small PHP script on your server which can interrogate the directories on the server and expose them in an easily digestible format, I’d suggest JSON.

Consumption

From here it’s pretty easy. You have all of your templates and assets exposed somewhere now you just build some code to:

  • Connect to the JSON endpoint and display a UI somewhere to pick the version you want to use
  • Download that version of the templates.zip and extract it somewhere
  • Build data objects then pass them to mustache template of your choice through a mustache renderer then insert that into the page.
  • Include the necessary asset paths in your markup

Improvements

I spent quite a lot of time working on this and getting it working well so I am unable to share with you the exact solution we’re using in production but there’s plenty of scope for expansion

  • Implement an API Key so nobody can easily rip of your site by pulling your templates and assets
  • Standardise your JS development, all our code is developed in ES2015 and transpiled back
  • Keep a close eye on your javascript to keep it free from bloat. I’ve banned jQuery and other libraries unless absolutely necessary, most of the time they’re not
  • Use HTTPS over HTTP2 in production. You’ll benefit from multiplexing