Skip to content

Minifying Handlebars templates

duncanbeevers edited this page Sep 5, 2014 · 1 revision

For the most part, Handlebars templates are valid HTML. The interpolator recognizes double-curly bracket constructs in plain text, inside the values of element attributes, and surrounding element attributes. There are two Handlebars-valid constructs whose usage results in invalid HTML.

Intra-attribute values

In Handlebars, it's possible to use helper methods which receive arguments. When these methods are used inside an attribute value, String arguments can turn good HTML into invalid HTML.

Consider this case of choosing a glyphicon based on a model attribute value.

This is valid HTML

<i class="{{#is type 'music'}}music{{else}}film{{/is}}"></i>

This is invalid HTML

<i class="{{#is type "music"}}music{{else}}film{{/is}}"></i>

Here we see the argument 'music' passed to the is helper method. Had the argument been double-quoted as "music", Handlebars would still recognize the expression and render the correct class name, but the HTML parser, having no knowledge of Handlebars constructs, terminates the expression at the first internal double-quote (").

If you double-quote attribute values in HTML, single-quote string arguments passed to helpers in those contexts.

Attribute surrounding values

Some DOM elements support boolean attributes whose presence causes a change in the behavior of the element. For example, the disabled and checked attributes on a <input type="checkbox" /> disable and check the input, respectively, regardless of the value of the attributes.

In order to render conditionally-checked checkboxes from Handlebars, typically the presence of the attribute is controlled through a conditional surrounding that attribute.

<input type="checkbox" {{#if enabled}}checked{{/if}} />

Unfortunately, this construct is invalid HTML, and due to the nature of HTMLs behavior regarding the presence and absence of such attributes, there's no simple workaround. Fortunately, HTML minifier makes special provision for parsing these invalid expressions.

Simply configure the minifier to recognize Handlebar's double-curly bracket pair surrounding element attributes.

var hbAttrWrapOpen = /\{\{#[^}]+\}\}/;
var hbAttrWrapClose = /\{\{\/[^}]+\}\}/;
var hbAttrWrapPair = [hbAttrWrapOpen, hbAttrWrapClose];

var minifier = require('html-minifier', { customAttrSurround: [hbAttrWrapPair] });

Note that these expressions are used for parsing individual attribute+value pairs, so a single Handlebars expression may not span multiple attributes. For example, the following markup would not be recognized.

<img src="logo.svg" {{#if logo_title}}alt="{{logo_title}}" title="{{logo_title}}"{{/if}} />

Instead, each attribute must be individually wrapped.

<img src="logo.svg" {{#if logo_title}}alt="{{logo_title}}"{{/if}} {{#if logo_title}}title="{{logo_title}}"{{/if}} />