/labcoat

Pattern Lab for Production

Primary LanguagePHPUniversity of Illinois/NCSA Open Source LicenseNCSA

Labcoat: Pattern Lab for Production

Labcoat is a library for using Pattern Lab content in live site environments. It provides the ability to:

Labcoat places the following restrictions on Pattern Lab installations:

  • Twig is the only supported templating language
  • Patterns can only be referenced by partial and path syntax
  • Layouts, macros, and other advanced Twig features are not supported

Labcoat was created by Pixo, and released under the NCSA license.

Pattern Lab was created by Brad Frost and Dave Olsen, and released under the MIT license.

Basic usage

Include the Labcoat library using Composer:

{
  "require": {
    "pixo/labcoat": "^1.0.0"
  }
}

The PatternLab class represents a Pattern Lab installation. For Standard Edition installations, Labcoat needs the path to the installation root (containing config and source directories):

$labcoat = Labcoat\PatternLab::loadStandardEdition('/path/to/patternlab');

For an installation that uses Labcoat's default structure:

$labcoat = Labcoat\PatternLab::load('/path/to/patternlab');

For custom configurations, create a new Configuration object and use it as a constructor argument:

$config = new Labcoat\Configuration\Configuration();
$config->setPatternsPath('/path/to/pattern/templates');
$labcoat = new Labcoat\PatternLab($config);

Rendering pattern templates

Labcoat contains a Twig loader class for using pattern templates in other applications.

$loader = new Labcoat\Twig\Loader($labcoat);
$twig = new Twig_Environment($loader, ['cache' => '/path/to/twig/cache']);

The loader supports two methods of including patterns:

  • Partial syntax, i.e. type-name. Fuzzy matching is not supported.
  • Path, relative to the patterns directory. The file extension and any ordering digits are ignored.
# These will all render the template "00-atoms/01-icons/email.twig"
print $twig->render('atoms-email');
print $twig->render('atoms/icons/email');
print $twig->render('00-atoms/01-icons/email');
print $twig->render('00-atoms/01-icons/email.twig');
print $twig->render('123-atoms/456-icons/email.twig');

# Fuzzy matching isn't supported, so this won't work
print $twig->render('atoms-em');

Caching the loader

Once created, the loader class can be stored in a cache to save time during the next request. If Memcache is available:

$makeLoaderIfNotInCache = function ($cache, $key, &$loader) {
  $labcoat = Labcoat\PatternLab::load('/path/to/patternlab');
  $loader = new Labcoat\Twig\Loader($labcoat);
};
$loader = $memcache->get('labcoat_loader', $makeLoaderIfNotInCache);
$twig = new Twig_Environment($loader);

If Stash is being used:

$item = $stash->getItem('labcoat/loader');
$loader = $item->get();
if ($item->isMiss()) {
  $item->lock();
  $labcoat = Labcoat\PatternLab::load('/path/to/patternlab');
  $loader = new Labcoat\Twig\Loader($labcoat);
  $item->set($loader);
}
$twig = new Twig_Environment($loader);

Combining with other loaders

The Labcoat loader can be chained with other loaders:

$loader = new Twig_Loader_Chain([
  new Labcoat\Twig\Loader($labcoat),
  new Twig_Loader_Filesystem('/path/to/more/templates'),
]);
$twig = new Twig_Environment($loader);

Creating HTML documents

The Document class makes full HTML pages from patterns:

$doc = new Labcoat\Html\Document($twig->render('pages-about'));
$doc->setTitle('About Us');
$doc->includeStylesheet('/css/styles.min.css');
$doc->includeScript('/js/script.min.js');
print $doc;

Generating style guides

Labcoat can generate style guides that use the Pattern Lab interface

$labcoat = new Labcoat\PatternLab('/path/to/patternlab');
$styleguide = new Labcoat\Styleguide\Styleguide($labcoat);
$styleguide->generate('/path/to/styleguide');

Use PHP's built-in webserver to browse the style guide locally (at http://localhost:8080, in this example):

php -S 0.0.0.0:8080 -t /path/to/styleguide

Reporting

The generate() method returns a report object, which can be printed to obtain a summary of the generation process:

print $styleguide->generate('/path/to/styleguide');

Which produces something like:

443 files updated, 0 skipped, 0 removed
Generated in 1.432264 seconds

To get a full report of style guide file changes, use the verbose() method of the report:

print $styleguide->generate('/path/to/styleguide')->verbose();
...
index.html
  Updated (0.60 ms)
styleguide/data/patternlab-data.js
  Updated (1.41 ms)
annotations/annotations.js
  Updated (0.52 ms)
latest-change.txt
  Updated (0.18 ms)

443 files updated, 0 skipped, 0 removed
Generated in 1.432264 seconds

Validating template content

Labcoat can use pattern data files to validate classes that will represent live content in production environments.

For example, a template named molecules-event could have the following data file:

{
  "event": {
    "name": "Company picnic",
    "date": "August 25",
    "time": "1:00pm",
    "private": true
  }
}

In production, the event variable will be an instance of the Event class. This class has properties and methods that Twig will treat like attributes of the variable.

class Event {
  public $name;
  public function getDate() ...
  public function isPrivate() ...
}

Labcoat provides test methods to ensure that the Event class has all the attributes of event which are present in the data file.

class EventTest extends Labcoat\Testing\TestCase {
  public function testEvent() {
    $labcoat = new Labcoat\PatternLab("/path/to/patternlab");
    $this->assertPatternData($labcoat, "molecules-event#event", "Event");
  }
}

When this test is run, the output will be something like this:

There was 1 failure:

1) EventTest::testEvent
Failed asserting that the data classes contain the required pattern variables.

molecules-event#event.name
  FOUND: Event::$name
molecules-event#event.date
  FOUND: Event::getDate(), line 15
molecules-event#event.time
  NOT FOUND
molecules-event#event.private
  FOUND: Event::isPrivate(), line 22