Building a Static Blog with Metalsmith
What is Metalsmith?
Metalsmith is a platform. It’s a platform that allows the developer to plug and play modules — these modules can be anything from compilers for SASS, to Markdown to HTML transformers, to Gulp aides, to just about any other content processing a web developer needs.
We’re going to use it to make a statically presented blog — Metalsmith is excellent for this, to the point that it can mimic Wintersmith or Jekyll, which can be a huge benefit. That’s awesome, but we’re going a different path: rolling our own, completely custom blog, with a few additional website functions.
Getting Started
To get started with Metalsmith, we’re going to need to create a local directory where our project can live, and set it to the current active directory. Let’s do that:
https://gist.github.com/19ee3c5ab22540c58d0118007c07604b
We need to initialize our repository with an npm package.json. I am going to throw the --yes flag in there, so we don't need to worry about the initial values of the content of package.json.
https://gist.github.com/50d203165de731eb673945d2abf66404
Now, we’re going to need to install Metalsmith. We’re going to save Metalsmith with the npm flag --save-dev -- the same goes for all the other plugins we are using for our blog. This command automatically adds a module to the devDependencies object in our package.json. Why? Doing this allows us to install modules only when we're in a development environment. We're always in a development environment with Metalsmith, until we are finished and ready to publish our Wintersmith project to the web.
https://gist.github.com/17d75459d3dba1db65841818579aada5
Now we have a foundation for our metalsmith project!
Setting up the site
package.json
You should open package.json, and change the value in "main" to "build.js", or whatever you want to call it. I call it build because we're going to run it every time we want to rebuild the static Metalsmith files in the build directory.
https://gist.github.com/4fd54f090f1d0ea6005cb66bb5bee265
Feel free to edit any of the information in package.json to reflect the scope of your project. If you're going to publish the actual project, not just the build result, to somewhere like GitHub, having this information filled out makes things a lot easier for managing the codebase.
build.js
Go ahead and create a build.js file in your metalsmith directory, and open it in your text editor of choice. Let's add the basics of a Metalsmith project to it:
https://gist.github.com/378107a11075a04beeb8c4ff606291ba
In this code, we’re requiring the Metalsmith module from node_modules (which we downloaded earlier via npm install metalsmith --save-dev) and assigning it to a variable named metalsmith. We call the Metalsmith module's main function, and pass __dirname. Finally, we call the Metalsmith module's build function, which initiates the build process.5
Installing dependencies
There are several dozen Metalsmith modules that are useful to accomplish a variety of tasks within Metalsmith. A good number of them are for writing and publishing, which is what we’re looking to use. Here’s the list of the Modules we’re going to use from that list:
Additionally, we need to install Handlebars as our templating engine.
Let’s install these packages and save them as devDependencies in package.json.
https://gist.github.com/211692528f110815f7d94a69a504782d
Authoring build.js
Let’s build our build.js file, using the above plugins. Each plugin call is annotated below, so we can understand what they're doing. Here it is:
https://gist.github.com/fb674dff784fb178618ae08e1dd90875
Directory Structure.
Now that we’ve got our build.js in place, we need to build the directory structure that it scaffolds. Create each of these folders and files in their respective places:
https://gist.github.com/811c5e50ea78f692e921ef662babfffd
Templates: index.hbs & blog-post.hbs
Templates are the foundation for content in our Metalsmith blog. Both the index file and all blog posts are routed through their respective templates, which produces our site with the structure we want.
Our index file allows us to list all our posts in one place, where someone interested in looking at our writing can find all of it.
The current implementation is only title, date, and two vector scrolls that have been exported to view on the page. There are a ton of other Metalsmith plugins that can help you further build your index — excerpts, pagination, tagging, and many others are available. Metalsmith is an incredibly simple plug-and-play tool, so it won’t be hard to integrate other features you may want.
Here’s our index.hbs, with functionality commented where appropriate:
https://gist.github.com/402ec69caf470106111efe2d5ad5196d
Our implementation of our blog post page uses a humongous element, and then prints the contents of the Markdown file after it has been converted to HTML by metalsmith-markdown.
Here’s our blog-post.hbs template:
https://gist.github.com/5d975ab6680ea70be1a50a19c74119c5
Partials: html-head and header
Partials in Handlebars are snippets of code that you can reuse in multiple places within your project — including them is simple — use the following syntax to do so:
https://gist.github.com/72e08c5c354c23277c448f2b1e866419
partial-name would be the filename of the partial located in the partials/ directory in the project root. The inclusion of partials will be noted when they are used in the handlebars layouts.
This is our html-head.hbs partial, which defines the head HTML element in all our pages:
https://gist.github.com/fef4f555a5411e0fb248e31157fa6530
Additionally, we are defining a header partial element that will be consistent across all our pages, including the index, blog post, and any other pages you may create.
Here’s our header.hbs partial: https://gist.github.com/4f18bb09fb3918e2e499611d6e8d2b98
src: content management
We’re almost done building our blog! The only thing that’s left is our content. Our content lives in the src/ (shorthand for "source") directory. The content comes in two forms: the core file (index.md), which simply calls the index.hbs template with no actual markup of its own, and content files (post-title.md), whose content iteratively gets piped into the blog-post.hbs template.
Learning src: front-matter
Front-matter is an important tool in Metalsmith. It is metadata content put at the top of your source files that help Metalsmith plugins and Handlebars (or other templating engines) templates parse the content of your site correctly.
Here’s an example of front-matter:
https://gist.github.com/89b9f7e5fbd9431e113a9dbbffdc79b8
Each of the items listed here gives data to one plugin or another. title gets used when {{ title }} is called in Handlebars. layout determines what layout the document is applied to. collection is an organizer of content. slug is used to create links to individual posts in the index. posted is a human-readable date that we display on both the index and the blog-post templates. And date is a machine-readable date that is for standardized record keeping and search engine crawling.
src: index.md
https://gist.github.com/e471a8021d081bfb73e4c7d161fe20e1
As you can see, its content is only a non-breaking space. This is because we define all the generated markup in the index.hbs layout, and don't need content to be inserted from this file.
src: .md
The strategy of no internal content is the opposite of files in our src/post/ directory. They include similar, but more detailed, front-matter. The difference is that to make a new post, you write below the front-matter in Markdown. Let's take a look at one of my personal blog entries:
https://gist.github.com/3584a628a6d23023da7c28f7eced0b7b
As you can see, the front-matter is defined and provides useful information that is utilized throughout the site. Below the front-matter is simple content, which is translated into the body of your blog post. So, we’ve got content! Now we need to style.
Assets: CSS
The blog’s CSS assets are important. They create the visual structure of your blog, which is an important factor in getting readers. This part can be largely changed by you to fit your stylistic views — the code presented here is a working example of how it can be done, but not exclusively how it should be done. You get to be creative here — you’ve got the templates, partials, and content. Make it yours!
Here’s how I wrote my base main.css file:
https://gist.github.com/8251b8c3d20a2ff228d68fe2e4367c3e
Next, I filled out my index.css file:
https://gist.github.com/f65a3b79ef26c506c740148e77d93f69
Finally, I wrote my blog-post.css fie:
https://gist.github.com/df3bc085d7c44e134d7c05ed51b15d47
And, with that, we have built a blog.
Conclusion
Metalsmith is an extremely powerful tool for building websites. It’s plug-and-play capability leaves the implementation of the site up to the creator. This is one of my favorite features, as it allows me to create my site the way I want it with precision accuracy.
There’s no end to what you can do with Metalsmith — you now have an idea of how to develop a site with it, and I think you can tweak it to match your idea of a perfect website with just a bit of work.
Originally published to my personal blog on December 11, 2015 at 9:10AM. Currently moving the contents of that blog to live on Medium.
