Skip to content

Advanced example with nunjucks template inheritance

Werner Glinka edited this page Jul 24, 2018 · 4 revisions

Instead of using metalsmith-layouts for template inheritance, it's also possible to use a language that supports inheritance directly with metalsmith-in-place. In this case we'll use nunjucks, a powerful templating language that's easy to use and supported by mozilla.

Install metalsmith and metalsmith-in-place:

$ npm install metalsmith metalsmith-in-place

Install appropriate jstransformers

We're using nunjucks, since it natively supports template inheritance, so we'll also need to install jstransformer-nunjucks:

$ npm install jstransformer-nunjucks

Configure metalsmith

We'll create a metalsmith.json configuration file and a file for metalsmith-in-place to process:

./metalsmith.json

{
  "source": "src",
  "destination": "build",
  "plugins": {
    "metalsmith-in-place": true
  }
}

./src/index.njk

---
body_title: "Post title"
---

{% extends "./templates/base.njk" %}

{% block body %}
  <h1>{{ body_title }}</h1>
  <p>Some text here</p>
{% endblock %}

The {% extends %} tag tells nunjucks that this template extends the base.njk template. The {% block body %} tag defines some content that will be put in that block in the base.njk template.

./templates/base.njk

<!doctype html>
<html>
  <head>
    <title>My blog</title>
  </head>
  <body>
    {% block body %}{% endblock %}
    {% include "./partials/footer.njk" %}
  </body>
</html>

As you see, we're also including a partial, called footer.njk, just to show how that would work with nunjucks:

./templates/partials/footer.njk

<footer>Copyright and such</footer>

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>My blog</title>
  </head>
  <body>
    <h1>Post title</h1>
    <p>Some text here</p>
    <footer>Copyright and such</footer>
  </body>
</html>

An important gotcha in using the extends tags with nunjucks: files located in the src folder are transformed by metalsmith into an object, and thus are read from memory and not from disk when processed by nunjucks. This means that nunjucks cannot resolve relative paths for files in the src folder as it doesn't know where they are on disk. That's why the extends tag in ./src/index.njk must be relative to the root of the project: ./templates/base.njk, so that nunjucks can find the base template.

Files located outside the src folder are not stored in memory by metalsmith and thus nunjucks can resolve relative paths for those files. That's why the include tag in ./templates/base.njk is relative to the base.njk file: ./partials/footer.njk.