github dribbble twitter facebook google arrow-up arrow-down arrow-left arrow-right menu close

First Impressions of Wintersmith, a Flat File CMS

October 31, 2015

Ever since I became active with creating open source projects on GitHub, I’ve been trying to figure out a good way to create documentation. My first attempt at a solution was something I called BaseDemo. I used this to create simple, one page documentation sites for a while, but it didn’t really scale well for larger projects.

My second attempt came when I started using build scripts in my workflow with Node.js and Jake. I developed a new project called Jake Builds which was a collection of node module wrappers I used in my scripts. In this project I had developed a Mustache wrapper that allowed me to generate static HTML files using layouts, templates and partials as well as inject variables using JSON.

I eventually ran into limitations with this solution, too. I needed to find a way to incorporate more complex content trees. Not really sure how to do this with my current Mustache script, I wanted to see if someone already came up with a solution I could either learn from or use. My only requirement was that it be written in Node so I could incorporate it nicely into my build scripts. In my search, I found this directory of flat-file CMS’s and with a quick Ctrl+f, I found the only one written in Node: Wintersmith.

It’s intimidating to learn new things. The feeling “I have no idea what I’m doing” is pretty common. Here are the things I learned after diving into Wintersmith:

It’s written in Coffeescript

This is probably not a problem for most developers but for me, this was a huge let down. I’m not the best JavaScript developer but I know it well enough that I can usually deconstruct a script and understand how it works. But I’ve never written or read Coffeescript before. This alone meant that I wasn’t going to be able to pull any content tree functionality and use it in my own projects. I was either going to use Wintersmith as is, or move on.

It uses Jade, a Node template engine

Another new technology that I had never used before—which adds to the learning curve. Looking through the default template examples that came with Wintersmith, I already hated it. Maybe just because it was new, but the syntax alone made me cringe a little.

You can of course use whatever template language you want and I found through the plugins directory that someone had already written one for Handlebars (which is super similar to Mustache). But since all the default template examples are written in Jade, I needed to use them to figure out how it all worked.

The quick-start guide is simple and easy

This was my saving grace. I could get Wintersmith running and test it out with just a few simple terminal commands. It’s easier to learn something when you use it in a practical way, so I decided to create a personal site with some static pages and a blog as my learning experiement. The first step is to install it locally:

$ npm install wintersmith -g

Now that I have the Wintersmith commands available, I started my project:

$ wintersmith new sebnitu.com

This creates my new project in the sebnitu.com directory. After navigating into this new directory, I now have available a preview and build command:

$ wintersmith preview

This launches a Node server at http://localhost:8080 and lets me view my project in real time while I play with the files.

$ wintersmith build

The build command lets me generate all the static HTML files for my project. This was one of the reasons I love the idea of using a flat file CMS. It means I can have all the benefits of a template system and still have super fast and light weight HTML files for production. This couldn’t be more simple.

Every page in Wintersmith has its own directory

Kind of weird to me at first, once I understood why and how this worked, it’s actually pretty cool. Essentially, this does a few things:

  • There’s no need for a .htaccess file to remove the extensions off files since the url requests are just navigating through folders and serving up index.html be default.
  • You get to encapsulate all assets that only apply to a specific page or article within its own directory. The blog example they provide demonstrates this very nicely.
  • It makes it straightforward to create a project structure and know exactly how those pages are requested.

Writing pages in Markdown is heaven

I’ve always loved writing in Markdown and it was actually a planned feature I wanted to eventually add to my own Mustache scripts, so this was a very big plus for me. I could easily write Markdown in whatever text editor I preferred while at the same time write any vanilla HTML as needed. Try doing that in your average database driven CMS.

It’s not very clear what variables are available to which templates

This was where most of my frustration came from. I actually caught on to how Jade works fairly quickly even though I still thought the syntax was ugly as hell. But just trying to figure out how to get a list of pages from a specific directory was a pain.

For my personal site, I started by using the base templates from the default blog example. This was fine, except that I wanted to move the blog listings page into a sub directory and have a static homepage separate from the blog. After some trial and error, I discovered that what made the articles listing available to the index.jade template was actually being set in pagination.coffee the default pagination plugin.

So I had to change the default settings of the pagination plugin by editing the config.json like so:

"paginator": {
  "template": "articles.jade",      // default: index.jade
  "first": "/articles/index.html",  // default: index.html
  "perPage": 100                    // default: 2
}

With those new settings, I created the articles.jade template where I moved all the old code from index.jade. I then also had to create an index.md file in the root of the /articles/ directory with these settings at the top:

---
title: Article Listing
template: articles.jade
---

Now I could just put whatever homepage markup I needed in index.jade and that was exactly what I needed.

But what if I want to create another content list somewhere else? What if I didn’t want to use the pagination plugin at all? Luckily, I found a script someone else put together with the function I needed to do just that. You can save that file in your plugins directory, add it to you plugins list in config.json and use it like this in your templates:

- var articles = env.helpers.getSortedContentFolder("articles", contents)

Where "articles" is the directory you want to pull content from.

Conclusion

After figuring out how to create the site structure I wanted and finally feeling comfortable with Jade, I started to see how powerful and flexible Wintersmith really is. I even decided to launch my experiment website as my personal site and use it for blogging (you’re reading it now!).

My next Wintersmith projects will include using it to power the documentation of BaseWeb, writing some Wintersmith plugins for common site components and even creating some tutorials to share all the new things I learn. I’m excited about Wintersmith and can’t wait to see what else I can do with it.