Skip to content

Advanced example with markdown and nunjucks

Kevin Van Lierde edited this page Dec 3, 2022 · 3 revisions

When writing our source files in markdown with some nunjucks variables, it's nice to not have to repeat certain page elements over and over. In that case it's nice to use @metalsmith/in-place with @metalsmith/layouts, so that the repetitive elements can be abstracted to a central layout.

Install metalsmith, @metalsmith/in-place and @metalsmith/layouts:

$ npm install metalsmith @metalsmith/in-place @metalsmith/layouts

Install appropriate jstransformers

In this case we're using nunjucks and markdown, so we'll also need to install the appropriate jstransformers:

$ npm install jstransformer-nunjucks jstransformer-markdown

Configure metalsmith

We'll create a metalsmith.json configuration file and the files we want to process:

./metalsmith.json

{
  "source": "src",
  "destination": "build",
  "plugins": [
    { "@metalsmith/in-place": {} },
    { "@metalsmith/layouts": {} }
  ]
}

./src/index.md.njk

---
title: Hello title ;-)
heading: The page heading
layout: body.njk
---
# {{ heading }}
Some text here.

./layouts/body.njk

<!doctype html>
<html>
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    {{ contents | safe }}
  </body>
</html>

First, @metalsmith/in-place will process the source file extensions from right to left. So it will process the file with nunjucks to replace the variable and then transform the markdown to html. After that @metalsmith/layouts will render the contents in the body.njk layout.

Build

To build just run the metalsmith CLI (note that you'll need npm@5.2.0 or higher to use npx):

$ npx metalsmith

Which will output the following file:

./build/index.html

<!doctype html>
<html>
  <head>
    <title>Hello Title ;-)</title>
  </head>
  <body>
    <h1>The page heading</h1>
    <p>Some text here</p>
  </body>
</html>

For more in-depth examples of various @metalsmith/in-place, @metalsmith/layouts and nunjucks build processes, see this blogpost by Werner Glinka.