Templating in Metalsmith can get messy with lots of different plugins all sort of trying to work together.
- perform layouting with handlebar templates
- and recursively template the contents
- include partials from a folder
- insert helpers from a folder
- anything but Handlebars (maybe later)
- load lots of unnecessary dependencies
- forget to load partials
- fail to load helpers from a parent directory
- ever give you up, or ever let you down
This is a plugin that combines 3 or 4 other plugins and tries to do it right.
It's core capability is perform Handlebar templating on a multi-directory
project. Your layout templates can be .hbs
, your immediate pages can be
.hbs
, your extra-fancy plugin that loads pages over rsync can be .hbs
.
At each of these levels you can use the same global context variables (provided by Metalsmith metadata and Yaml Front Matter), and the same helpers, and the same partials.
Enjoy!
layouts/ - for your master .hbs layouts
partials/ - for your .hbs partials
helpers/ - for your .js helpers
public/ - output directory
src/ - input directory
metadata.json - global context
Metalsmith(__dirname)
.source('./src')
.destination('./public')
.metadata(require('./metadata.json'))
.use(handlebars({
layouts: 'layouts/',
partials: 'partials/',
helpers: 'helpers/',
}))
{
"siteTitle": "Wassup",
"author": "Me."
}
<!DOCTYPE html>
<html>
{{> head }}
<body>
{{{ contents }}}
</body>
</html>
<head>
<title>{{ siteTitle }} - {{ page }}</title>
<meta name="author" content="{{ author }}"/>
</head>
---
layout: main.hbs
page: 'hey.'
---
<div class='container'>
{{ titleHelper }}
</div>
// helpers/titleHelper.js
module.exports = titleHelper function() {
return `
<h1>${this.page}</h1>
<h2>By ${this.author}</h2>
`;
}
<DOCTYPE html>
<html>
<head>
<title>Wassup - hey.</title>
<meta name="author" content="Me."/>
</head>
<body>
<div class='container'>
<h1>hey.</h1>
<h2>By Me.</h2>
</div>
</body>
</html>
Not demoed here, but a particular use-case is in conjunction with
the metalsmith-collections plugin. This plugin hoovers up files of a
sub-directory of src/
and these files also may need templating.
This plugin will template these appropriately. Given that they don't have
a layout
property in their YAML header, they will instead render in-place
without applying a layout template.