I recently went through the process of changing this site from a being generated with gatsby to Eleventy . I've heard nothing but hype for Eleventy and needed something to try it out on. Since the projects I do at work have requirements that keep make Eleventy not a viable option, I decided to give it a shot with this blog. The idea of simplifying also intrigued me because the infrequent nature of me updating this. Any time that I would come back to work on this site, Gatsby would throw a fit and I'd be left in dependency hell working through updates until everything decided to work today. It's part of an ever increasing fatigue I'm feeling for the JS ecosystem, despite also thinking it's the best out there. Both of these things are better suited for another post, so let's get to the good stuff.
Handlesbars is one of the default templating engines that comes out of the box with Eleventy. Having never really used a templating engine aside from pug years ago, I decided to go with this because of the familiarity in syntax that I saw between it and Vue or Svelte, both of which I have use regularly and enjoy immensely. I quickly found out, however, that while it is very much supported, the Eleventy ecosystem leans heavily towards Nunjucks as the templating engine of choice and examples of using Eleventy with Handlebars is sparse. Fortunately, the joy of Eleventy is that these templating engines just work for 90% of the use cases.
One area that I found lacking in particular, however, was the inability to extend layouts within Handlebars. Coming from a world of SPA frameworks for the past few years, I was expecting something like this children in React or slots in Vue to be front and center within a templating system. What I found, unfortunately, was that Handlebars didn't have a well documented solution for this. There exists a helper for Handlebars that gives it this functionality handlebars-layouts
but I quickly found out that registering that helper with Eleventy added some complication and issues that I wasn't able to overcome. Luckily for me, I found a blog post from 2016 that showed how you can replicate the features of handlebars-layouts
using features that exist in Handlebars without plugins through the use of inline partial declarations. This allows a user to create a reusable parent template that knows nothing about the children rendered beneath it aside form where they should live in the dom tree.
Something like this is best served with examples so let's get it.
First we can create a layout template that will serve as the parent. To keep things simple, I'll only include the relevant code. In this template, we need to specify where in the DOM we want our children to go by declaring a partial.
/layout/page.hbs
<body>
<nav> <!-- nav code here --> </nav>
<main>
{{> content-block }}
</main>
</body>
Next, we can create a page using this layout and add our children using an inline partial declaration of the same name as the partial declared in the parent.
/about-page.hbs
{{> layout/page }}
{{#*inline "content-block"}}
<h2>About Us<h2>
<p>Here is some really interesting information about us!
{{/inline}}
{{/layout/page}}
After Handlebars does it's magic, we will be left with
/about-page.html
<body>
<nav> <!-- nav code here --> </nav>
<main>
<h2>About Us<h2>
<p>Here is some really interesting information about us!
</main>
</body>
This technique allows the flexibility in structuring our templates into reusable chunks. This can support multiple inline partials as well, as noted in the above blog post. Currently on this site, I'm using named partial in two places on my blog post layout. It looks something like this.
/layout/blog.hbs
<head>
<!-- Plain ol' head stuff -->
{{> head-block }}
</head>
<body>
<sidebar>
<main>
{{> content-block}}
</main>
<footer>
</body>
This gives me access to inject some sweet SEO goodies into the head as well as set the title of the page to the blog post title.
Overall, I'm super happy with the switch to Eleventy and have really enjoyed using Handlebars. I think I probably missed the peak of it's usage, but it's great to see a project like this still be useful and developer friendly in the "everything is an SPA" internet of today.