Darren Mothersele

Software Developer

Warning: You are viewing old, legacy content. Kept for posterity. Information is out of date. Code samples probably don't work. My opinions have probably changed. Browse at your own risk.

Introducing Stylex: Atomic design, style guides, and prototyping with Silex and Twig

Mar 20, 2015

web-dev

I’ve been working a lot with Atomic design (component-based design) with Drupal recently, and I’ve witnessed huge improvements on projects where it has been introduced. The main advantage being the decoupling of the development of the back-end from the development of the front-end code.

I’ve covered this in more detail previously, I’m running some workshops on Atomic Design in Drupal, and I have more to say on this in the future. Today I want to tell you about a simple tool I’m using to speed up the process. Stylex.

The main purpose of this tool is to simplify the construction of prototype sites or style guides for front-end code. There are several tools already available, including the excellent Pattern Lab, but I wanted something incredibly simple.

I basically just wanted to make use of the power of Twig templates for mocking up front-end code, with an easy way to load in demo content (from yml files).

## Barebones project

I’ve created a barebones Stylex project on GitHub that demonstrates this, but you probably want to follow along in the setup, so you know what’s going on…

Basic setup

I’ve packaged this for Composer so getting started is easy. Assuming you already have Composer installed globally all you need to do is create a folder for your project and run the following command:

composer require darrenmothersele/stylex dev-master

This will download Stylex from Github and all the dependencies. It creates the composer.json file for you and downloads all the code for the dependencies into a vendor folder.

As a bare minimum you will need to create a index.php to run the application, and a starter template templates/index.html.

Create a file in the project root (same location as the generated composer.json file) called index.php with the following code:

<?php
require_once __DIR__ . '/vendor/autoload.php';

$app = new Stylex\Application();
$app->run();

Then create a templates folder and create the first page template, templates/index.html in this folder:

<html>
  <head>
    <title>Hello!</title>
  </head>
  <body>
    {% block content %}
      <h1>Hello, world!</h1>
    {% endblock %}
  </body>
</html>

You can run the application with PHP’s build in web server. Simply run the following command:

php -S localhost:8000

Now, browse to http://localhost:8000 to see the website.

Adding pages

You can add more pages, and make use of Twig’s awesome template inheritance feature. For example, to create an ‘About us’ page, create a new file in the templates folder called about.html with the following content:

{% extends 'index.html' %}

{% block content %}
  <h1>About us</h1>
{% endblock %}

This inherits the whole template from index.html but replaces the content block with a new block of content specific to this page. Browse to http://localhost:8000/about to see the result (make sure PHP’s web server is running - see above).

Using data

You can create YAML data files and then use them in your templates. Create a folder called data and then add *.yml files with your data. In any template these are then available using the filename. For example, to create a data file for your navigation links, create a file called data/main_menu.yml with the following content:

- title: Home
  path: /
- title: About Us
  path: /about

Because the filename is main_menu.yml this data is now available to read in template files using {{ main_menu }}. Let’s add a component template to style the menu. See my posts on Atomic design in Drupal to find out more about component templates. For now, just create a file in templates/components/menu.html with the following content:

<ul>
  {% for item in main_menu %}
    <li>
      <a href="{{ item.path }}">{{ item.title }}</a>
    </li>
  {% endfor %}
</ul>

Now you can include the menu in your page template, by adding the following to your index.html file:

{% include 'components/menu.html' %}

Using sample content

Stylex supports creating sample content using Markdown format with YAML front matter. This is a simple way to manage blobs of content with associated metadata. By using Markdown and YAML together to create sample content you can keep the sample content out of your front-end mockups and prototypes. This is another useful decoupling that makes life easier.

In this approach sample content is stored in subfolders under a content folder. You can have multiple types of content, and organise them into subfolders under a main content folder. Let’s create a first article as an example. First create your content and then content/articles folder, then create a sample file called content/articles/first_post.md with the following content:

---
title: My First Post
excerpt: Lorem ipsum dolor sit amet, consectetur adipisicing elit.
image: http://placebee.co.uk/640x480/1
---
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas ipsam veritatis officia unde incidunt doloribus veniam eligendi ea maiores delectus excepturi aspernatur illum, voluptates quas odit harum cupiditate cum maxime...

See the Stylex Barebones for the full example, I’ve abbreviated the content here. The main point is to show how you can include YAML metadata above the main Markdown formatted content.

You can then reference this content from your templates. For example, to print out the title of that first post you created, use the following in your Twig template:

{{ content.articles.first_post.title }}

Or, more useful, print out the titles of all articles:

{% for post in content.articles %}
  <h2>{{ post.title }}</h2>
{% endfor %}

Or, yet even more useful (if you’re building an atomic design), output all the articles using a component template:

{% for post in content.articles %}
  {% include 'components/teaser.html' with post only %}
{% endfor %}

For this to work, create a component template for the teaser by creating a templates/components/teaser.html file with the following content:

<div class="teaser">
  <h2 class="teaser-title">
    {{ title }}
  </h2>
  <img src="{{ image }}" alt="" class="teaser-image">
  {{ content|raw }}
</div>

You can create subfolders to organise different types of sample content, for example, add an events folder content/events and they will be available in your templates as {{ content.events }}

## Debugging

If you’re getting error messages, you can turn on debugging. In the index.php file that you created simple add the following line before $app->run();

$app['debug'] = TRUE;

Conclusion

This just does the basics to allow you to use Twig templates to quickly build out front-end code. It reads in sample content and data from yml files and allows you to easily combine them with template files to create a prototype site.

The next step is to reset Drupal’s markup and get it generating the exact same markup. This is covered more in my Atomic Design in Drupal workshops.

You’ll probably want to add your favourite front-end tools into this. In particular, I like to add a Gruntfile to do less/sass compilation, etc.

Drop me a line if you find this useful, or have any ideas for how it can be improved.

Thanks!

Darren