innovaniac.com
A blog about software development

Generating static HTML pages with Grunt + Assemble


Static HTML pages with Grunt From YAML to HTML using Grunt and Assemble

psst… for this article you need to know basics of Grunt.

Recently I embarked on creating the first completely static website in over a year. Before that most static websites done by me were simple landing pages for various web products. This project was to be done for a client that didn’t have and didn’t want to have a CMS; just a simple, static website.

The thing was, they have roughly thirty people working for them and all of the personnel were to have their own profile pages. It would be absolutely crazy to work those profile pages individually.

Data for the static page generation

The individual pages share a lot with each other which makes the HTML generation process well automatable. This, however, requires some data format to be fed into the templating engine. For legibility, I chose to go with YAML.

Data format

Here’s a simplified mock of the data as YAML:

—-
  first_name: “John”
  last_name: “Doe”
  experience:
    -
      title: “Helsinki Uni”
      year: “1995"
    -
      title: “Example Ltd”
      year: “1995 — 2008"
—-

The above is the content of a single YAML file. I had one for each profile in the personnel list with each of them named by the persons name as: surname_firstname.yml. All the profile data files were located neatly in the same directory.

Template format

Now that the data is set, I needed a HTML template. For each data file I want to have a HTML page. To avoid repeating manual work over all the profile pages on any minor or major change, I will simply edit the template and re-run the Grunt task to generate the static pages.

For that, I have a Handlebars.js template file, personnel.hbs:

<!doctype html>  
<html lang="en">  
  <head>
    <meta charset=”UTF-8">
    <title>{{ last_name }}, {{ first_name }} | Example Ltd</title>
  </head>
  <body>

    <h2>{{ last_name }}, {{ first_name }}</h2>

    <ul>
      {{#each experience}}
        &lt;li&gt;
          <span>{{ title }}</span>
          <span>{{ year }}</span>
        </li>
      {{/each}}
    </ul>

  </body>
</html>  

From the template above you can see that the properties in the YAML files can be directly accessed in the template file within the double braces. You can also use the builtin helpers, like `each, which is used in the example template above.

File structure

My desired end result is easily presented as file structures before and after the Grunt task.

Before:

<!doctype html>  
<html lang="en">  
  <head>
    <meta charset=”UTF-8">
    <title>{{ last_name }}, {{ first_name }} | Example Ltd</title>
  </head>
  <body>

    <h2>{{ last_name }}, {{ first_name }}</h2>

    <ul>
      {{#each experience}}
        &lt;li&gt;
          <span>{{ title }}</span>
          <span>{{ year }}</span>
        </li>
      {{/each}}
    </ul>

  </body>
</html>  

And after: assemble:personnel

Settings up Assemble

To generate the static HTML pages I turned to Assemble. As it reads on their website:

Assemble. The static site generator for Node.js, Grunt.js and Yeoman.

Installation is straight forward with NPM:

undefined


Configuring Assemble

Below is an example of my Assemble configuration. Please note, that my configuration is in CoffeeScript!

undefined

The above defines a task called assemble:personnel. In the options block I’m defining the template file to be used in the static HTML generation. You could also define path for finding partials in case your site consists of smaller pieces. The source files are all the YAML files (*.yml) and the destination is the root of my dist directory, where I want the finished HTML pages to appear.

Now run the task and enjoy
while the work gets done for you!

Tomi Hiltunen

Senior Full-Stack Developer @ Hubchat

Helsinki, Finland