Introduction
Pattern libraries are useful tools that help assist with the organization and swift development of patterns. A pattern library that is driven via Handlebars templating can be greatly enhanced by using layout blocks to template and nest patterns with. In particular, the handlebars-layouts library can be used for this reason.
One organizational schema that is useful in pattern libraries follows the structure: Elements -> Components -> Templates -> Pages. Elements are the simplest form of patterns, while pages are the most complete, being composed from other elements, components, and templates. We’ll refer to this schema.
Given our schema, handlebars-layouts allows us to implement the templates. For our templates, we can define a block (or multiple blocks) which designates the area in which we wish to host our other patterns in different variations. Overridable content/patterns may also be placed in the block by default, and when utilizing a template it is optional to define/override this block. This functionality usually allows us to visualize [with placeholders] the different areas of the template that can host patterns.
Installation
The library handlebars-layouts can be installed via a JavaScript package manager. Most popularly via npm with npm install handlebars-layouts
.
Depending on the Handlebars driven pattern library, registering the handlebars-layouts library may differ. But, we’ll show an example for registering and using the library with Fractal, a pattern library that can utilize Handlebars as the templating language for patterns.
In fractal.js, we can register the handlebars-layouts library as such:
const handlebarsLayouts = require('handlebars-layouts’); const instanceComponents = fractal.components.engine(); handlebarsLayouts.register(instanceComponents.handlebars);
Example #1: Base Template
In this first example, we can define a base page template to showcase basic functionality and usage. Our base template (base.hbs) has a block defined as “body“. The “body” block is surrounded by a <main> element, along with a Header and a Footer:
{{ render '@header'}} <main> {{#block "body"}} <!— Content that is overridden —> <div class=“placeholder-element”> Placeholder for Body Content </div> {{/block}} </main> {{ render '@footer’}}
Next, we’ll define a page (sample-page.hbs) and extend our base template (base.hbs). We can extend the base template to create a page with only some text content:
{{#extend '@base'}} {{#content 'body'}} <p class="sample-text">Sample page text content</p> {{/content}} {{/extend}}
And as a result, the following HTML will be generated from extending the base template:
<header>[...]</header> <main> <p class="sample-text">Sample page text content</p> </main> <footer>[...]</footer>
Example #2: Promo
Promo components are often authored in a CMS and can contain a wide variety of different elements and components. Additionally, Promo components often also have different author-able settings.
To make our sample page more robust, we can define a Promo that extends the same layout block functionality as a template. This allows us to easily and dynamically test out other patterns located inside of the Promo. Additionally, our Promo will accept a boolean option to enable/disable an overlay setting.
In our Promo (promo.hbs), we can label the layout block as “promo-content” and the overlay boolean variable as “promoHasOverlay“:
<div class="promo{{#if promoHasOverlay}} promo--overlay{{/if}}"> {{#block "promo-content"}} <!— Content that is overridden --> <div class=“placeholder-element”> Placeholder for Promo Content </div> {{/block}} </div>
Given the Promo, we can add it to our sample page, setting the “promoHasOverlay” value to true and including some sample text:
{{#extend '@base'}} {{#content 'body'}} <p class="sample-text">Sample page text content</p> {{#extend '@promo' promoHasOverlay=true }} {{#content 'promo-content'}} <p class="sample-text">Sample Promo text content</p> {{/content}} {{/extend}} {{/content}} {{/extend}}
And given the new Promo, we update our sample page (sample-page.html) with the following HTML:
<header>[...]</header> <main> <p class="sample-text">Sample page text content</p> <div class="promo promo--overlay"> <p class="sample-text">Sample Promo text content</p> </div> </main> <footer>[...]</footer>
Conclusion
Additional features are available with handlebars-layouts, such as embedding. Otherwise, the above uses of the layout block tooling provide robust functionality by being able to construct patterns from templates.
Leave a Reply