
Every year there is a development of technologies used by front-end developers. And here we are talking not only about specific frameworks and architectural patterns for implementing client logic in browsers, but also about various alternative tools, such as, for example, static site generators. Their main goal is to simplify the process of creating static sites. Of course, they are not a universal tool, but in some cases they fit perfectly:
- Web interface prototype
- A blog with infrequently updated content.
- Separate static part of another web application
- Site card or landing-page
- Online documentation
A more detailed comparative analysis of various generators can be found in
this article , as well as a
rating based on the activity of the relevant projects on github. We will consider, though not the most popular, but, nevertheless, an elegant and simple representative of this class of tools -
metalsmith .
')
Metalsmith
This generator is entirely written in javascript, the source code can be found in the
official repository . The concept of work can be divided into several stages: reading template files from the source folder of the site, sequentially processing them with plugins, and writing the results to the target directory.

At the moment
there are about 670 different plug-ins. If you still have not found something, writing your own plugin is completely easy thanks to a simple and understandable plugin-API. For example, a plugin that displays file names at a particular step might look like this:
function plugin() { return (files, metalsmith, done) => { Object.keys(files).forEach(name => console.log(name)); done(); }; }
Although, if you need (for example for debugging), you can use my plug-in -
metalsmith-inspect-files , which renders the tree of files and directories at the time of its use in the plug-in chain.
Make a simple blog
In order to demonstrate the capabilities of the tool, we will create a simple static blog with its help, all the code is available in the
repository . The configuration for the assembly is either in the metalsmith.json file, or directly in the script, and the latter, in my opinion, is most preferable, because it allows you to more flexibly configure the assembly process:
const Metalsmith = require('metalsmith'); const timer = require('./plugins/timer'); const jade = require('metalsmith-jade'); const layouts = require('metalsmith-layouts'); const permalinks = require('metalsmith-permalinks'); const collections = require('metalsmith-collections'); const less = require('metalsmith-less'); const ignore = require('metalsmith-ignore'); const cleanCss = require('metalsmith-clean-css'); const metalsmithInspectFiles = require('metalsmith-inspect-files'); const partial = require('metalsmith-partial'); Metalsmith(__dirname) .source('./source') .metadata({
Our blog consists of several separate separate pages and one collection of similar pages. Source directory structure (without external directories layouts and partials):
|-articles | |-article-one.jade | |-article-three.jade | |-article-two.jade | -index.jade |-assets | |-images | | -favicon.png | |-js | | -turbolinks.min.js | -stylesheets | -main.less |-about.jade -index.jade
And this is the result of the work (the contents of the build daddy):
|-about | -index.html |-articles | |-article-one | | -index.html | |-article-three | | -index.html | |-article-two | | -index.html | -index.html |-assets | |-images | | -favicon.png | |-js | | -turbolinks.min.js | -stylesheets | -main.css -index.html
Immediately noticeable is the work of the
metalsmith-permalinks plugin, which converts * .html files, whose name is different from index.html, to the corresponding directories with index.html, so that the url of these pages looks more pleasant. The main features of any static site generator are templates (layouts and partials), as a means to comply with the DRY principle (Don't repeat yourself).
Jade (or pug), popular among representatives of the javascript community, is used as a template language. So in our case, the main layout looks like, representing the page frame:
doctype html html head meta(charset='utf-8') meta(name='description' content='Simple metalsmith blog') meta(name='viewport' content='width=device-width, initial-scale=1.0') title=title link(href='/assets/stylesheets/main.css', rel='stylesheet') link(rel="icon" href="/assets/images/favicon.png") body .container nav!=partial('menu.jade', {menuLinks, currentPath: path}) section.page-content!=contents footer!=partial('footer.jade') script(src='/assets/js/turbolinks.min.js')
He, in turn, uses partials templates, the functionality of which is implemented by the
metalsmith-partial plugin (note the explicit transfer of variables for drawing the template). The included menu template is as follows:
ul.menu each page in menuLinks - isActive = ('/'+currentPath+'/').startsWith(page.url) && (page.url != '/' || page.url === currentPath + '/') li(class=(isActive ? 'active' : '')) a(href=page.url)=page.title
For iteration through the collection pages (articles), the
metalsmith-collections plugin is used, the pages themselves for generating the list are available in an array variable with the collection name.
Turbolinks
The
turbolinks library allows
you to 'animate' the content sent by the server with statics by adding the SPA behavior when clicking on links inside our website, loading the contents of each new page with AJAX and replacing the current one with it. In case if for some reason the request was long (more than 500 ms), a progress bar will be shown, which will inform the user that switching to another page is taking place (standard means by which the browser shows this when you simply click on the link will not be used due to the absence of a page reload), albeit slowly. Turbolinks in this example is connected in the form of a miniified distribution file, so to say “for the sake of simplicity”. If the javascript part of the site is not so simple, you should use something
like metalsmith-webpack-2 or
gulp-metalsmith .
Useful links and conclusions
Despite the fact that metalsmith is not the most popular of the generators, in my opinion, it deserves attention, because it is simple and flexible (almost any third-party tool can be embedded in the plugin-pipeline with a few lines of code), which means it can be used to create different sites, although, of course, it is not a 'silver bullet' and has its drawbacks. For example, most plug-ins do not have detailed documentation, so in order to understand the details of their work, you often need to study the source code, since they are almost always a simple facade, designed to adapt other popular tools with good documentation under metalsmith plugin-API.