Introducing Stylex: Atomic design, style guides, and prototyping with Silex and Twig
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:
<?phprequire_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 Postexcerpt: 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