Past weekend I spent playing with Metalsmith, which is an extremely simple, pluggable static site generator, written in JavaScript. This means package’s only responsibility is copying files from source to destination folder and in a process applying pluggable transformations to those files via external plugins (if you’ve ever used Gulp, this will look familiar to you).
Here is minimal, but useless example, because only thing it does is transferring files from src
folder in current directory to build
folder (which are default names).
var metalsmith = require('metalsmith');
metalsmith(__dirname)
.build();
Things start to get interesting if we are writing in markdown and would like files to be transformed to proper HTML. Simple, we just install and require metalsmith-markdown
and plug it into our app via .use()
method.
var metalsmith = require('metalsmith'),
markdown = require('metalsmith-markdown');
metalsmith(__dirname)
.use(markdown())
.build();
In my 2-days experiences of building static website with metalsmith, I found those plugins essential ((I also found out that the order of used plugins is very important.)):
- metalsmith-markdown
As mentioned, it transforms files from markdown format to HTML format. - metalsmith-templates
Use templates/layouts for a file. You specify which template/layout to use by addingtemplate
key in file’s YAML front-matter - metalsmith-collections
Group files by a pattern or specifying acollection
key in file’s YAML front-matter. - metalsmith-permalinks
Changes filename hierarchy so that conforms to desired urls. For example, it can change about.html to about/index.html.
Most plugins are built in a way that they accept configuration object and return a callback with 3 arguments – collection of files, metalsmith object and a done callback. The most interesting one is files, which is an object with filename as a keys and filename’s (YAML front-matter, content,…) data as a value and where plugins’ transformations are applied.
I used collections plugin in conjunction with permalinks plugin and immediately wasn’t satisfied with former one, since I wanted to have different permalinks per collection. So I forked this plugin on GitHub and applied desired logic. It can be found here. In a process I also learned you can use as a dependency a npm package hosted in public git repo. Instructions can be found here.