Skip to content

Instantly share code, notes, and snippets.

@jonschlinkert
Last active February 3, 2018 05:51
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jonschlinkert/9725714 to your computer and use it in GitHub Desktop.
Save jonschlinkert/9725714 to your computer and use it in GitHub Desktop.
Very powerful combination! Four helpers are used here: `each`, `expand`, `markdown` and `inline`.
{{#each (expand 'content/*.md')}}
{{#markdown}}
{{inline .}}
{{/markdown}}
{{/each}}

Handlebars Helpers

each is the generic build-in Handlebars block helper, so we'll focus on the other three custom helpers.

These helpers can be in other projects, but you'll need to do some custom coding of your own to make the inline helper work without Assemble (it does things like parsing YAML front matter, and other fun stuff).

Let's dive into the helpers.

expand

A powerful use case for handlebars subexpressions, the {{expand}} helper exposes Globule's find method to your templates.

Used as a generic handlebars expression (mustache) you can pass a glob pattern to the helper like this: {{expand "content/*.md"}}. But this returns an array of filepaths if matches are found, so unless something else is done to the result, the array that's returned would be pretty useless in the rendered HTML.

as a subexpression

However, when expand is used as a subexpression with the each helper things get much more exciting, making this combo a super powerful weapon in your templating arsenal!

For those who are unfamiliar with the wiley ways of our favorite mustachioed templating language, it's easier understand what's happening if we split things out.

First, although the expand helper is using the special subexpression syntax, (), it's just a regular helper that happens to be used as an argument to another helper.

This means that when the expand helper does its thing, e.g. expand files, you should expect it to, well, do its thing and return an array of files. For example:

(expand 'content/*.md')

Would be expected to return something like:

['foo.md', 'bar.md', 'baz.md',...]

Now, since the expand helper is being used as a subexpression, this array of files would be returned directly tooo... you got it, the each helper! If we were to capture super-slow-motion imaginary video of these templates actually being compiled by Handlebars, you might find a faux-frame or two with a picture that looks something like this:

{{#each ['foo.md', 'bar.md', 'baz.md',...]}}
  // do something with each file
{{/each}}

Nice! Just like a wood chipper (huh?), the each helper will suck in each file, sending it to its inner block to be processed further before its returned. Onward and inward!

inline

The each-expand duo is pretty dynamic, but this is where the real magic is happening!

The inline helper saws those logs, chips off the bark, and breaks everything down into smaller chunks before spitting it out the other end.

In literal terms, here's what's happening:

  • inline expects a single filepath to be passed as an argument
  • it reads the file
  • parses YAML front matter using gray-matter, which returns an object that includes "data" and "content"
  • extends the context with the data (in this case Assemble, but you can do this with other tools)
  • processes Handlebars templates using the now-extended context

Before you know it, the inline helper will be churning out markdown-flavored sawdust faster than you can say "streaming-node-task-build-runner"!

markdown

The markdown block helper is boring by comparison. It just cleans up by taking any markdown-flavored sawdust passed through its inner block, and converting it into, well... HTML! Who knew? sawdust => HTML.

Example:

{{#markdown}}
# Blog
{{/markdown}}

Renders to

<h1>Blog</h1>

That's it. If you want to see these helpers in action, feel free to look around the v3.0 docs for assemble.io:

Happy subexpressions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment