Design and Publishing Notebook

Using Ruby, Builder and Premailer to Create a Modular Email System

04 Dec 2014

Do you need to streamline the process of creating HTML marketing emails? This idea was recently explored in an article by Brian Graves on the Smashing Magazine website titled “Improve Your Email Workflow With Modular Design”:

He says:

“With the ever-growing number of emails to send, getting them all out the door can seem a little overwhelming. By putting in place a solid email design workflow, you’ll be able to regularly ship engaging and mobile-friendly emails with ease.”

He asks the question: “How do you structure your workflow to allow for continual iteration and quick turnaround?” and offers Modular Design as a solution:

“Modular design is the method of creating a system of self-contained components that can be stacked, rearranged and used or not used, case by case. The goal is to be able to easily change or adapt individual design patterns without altering the system as a whole. Adopting modular design and reusable patterns into your email design workflow can improve the quality and consistency of what you send, while speeding up your daily output.”

Setting up a modular email design workflow involves three basic steps:

  1. Create the design system.
  2. Set up a re-usable framework.
  3. Test and iterate on what you send.

The design system (Step 1), is the set of building blocks which you can fit together into layouts like pieces of Lego.

I want to focus here on Step 2 — setting up a re-useable framework. The Smashing Magazine article continues:

“If you send a decent volume of email, then creating your own custom framework could lead to huge gains. By creating your own framework, you can add in time-saving custom helpers, keep the markup light and easy to work with, and even hook directly into your email service provider. Not to mention that you can create more customized layouts to complement all-in-one solutions. The long-term gains in quality and efficiency from setting up your own framework can be huge.”

The article then goes on to examine the idea of building on top of a static website generator, such as Middleman.

I’d like to discuss another kind of modular construction system for generating HTML emails. It works by using Ruby scripts to generate the email, and using the Builder library to generate correct HTML code.

I’ve been developing and using this approach for the past three years. It’s a practical and powerful option if you have programming experience and are comfortable writing Ruby code.

Simplifying the Complexities of HTML Email

As you know, to get your HTML emails to display reliably on a broad range of email clients, it’s necessary to resort to table-based layouts and in-line CSS. But writing that kind of complex code by hand is tedious and error-prone.

With a modular construction system you can hide all that complexity inside building blocks, enabling you to write simpler code at a more abstract level. The construction system then handles the generation of all the complex HTML and in-line CSS.

How Does it Work?

Let’s follow the process. First create a subclass of the Builder class — call it NewsBuilder.

NewsBuilder < Builder::XmlMarkup

The new class will then inherit Builder’s useful HTML-generating behaviours. For example, if you want to generate a table tag pair, you just write:


…and Builder’s method_missing method will catch this and generate a table tag pair for you.

You create nested tags like this:

table {
    tr {
        td {
            content here

You can define your own “tags” such as:

def table_default(*args, &block)
    table(*args, cellspacing: 0, cellpadding: 0, border: 0, &block)

…which will generate a table tag pair with default attributes for cellspacing, cellpadding and border. You can then use table_default as if it was a standard HTML tag. But you can go much further than that, creating methods that define entire substructures of nested tables.

The benefit is that you can define your own “building block” methods within the NewsBuilder class to do things like:

  • Construct an “outer” table for your email with all the desired attributes pre-filled, including width, background color, etc.
  • Construct a multi-row, multi-column table to simulate a container with css padding. Remember that certain essential css properties are ignored by some email clients — hence the common recommendation to avoid these and use nested tables and dummy rows/columns to emulate padding, margins, and so on.
  • Build entire re-useable sub-sections of your email and use Ruby blocks to pass in the custom content.

The process is not unlike using a static website generator and creating a series of “partials” to encompass commonly used structural building blocks. In that case you are working in HTML code and escaping into a programming language when required. Using the Builder approach, you are working in Ruby code and escaping into HTML when required.

Once you’ve generated your table-based layout and written a CSS file to style it, you then need to move the styles inline. This is where you can use the Premailer gem to move all relevant CSS styles inline and attach them to the HTML elements on which they would have an effect if the HTML + CSS combination were rendered by a browser.

This allows you to continue using CSS and a CSS preview tool, such as CSSEdit or Espresso, to write and refine your CSS, prior to shifting it all out of the style sheet and moving it inline in the HTML code. Premailer is a cool piece of software and you can link the Premailer gem directly into your Ruby code so that it runs seamlessly each time you render your email.

The great thing is that you can run all this as a scripted workflow, with variables or constants used to configure the generation process and as “switches” to control the workflow — e.g. whether you are rendering locally during development, or whether you want the urls made absolute, ready for uploading to an email provider.

As with all automation, there is an up-front investment of time required to design, develop and debug the process. But once you’ve done that, you can reap the benefits of an automated workflow that reduces the setup work for each new email to the minimum.

Recent Posts: