Setup

Installation

Barbiche is available as a npm package:

npm install barbiche

Polyfills

For decent browser support, using some polyfills is required. Good results can be obtained with:

  • template (available as npm package template-mb)
  • classList.js (available as npm package classlist.js, only needed for IE9 support)

The polyfills are included in Barbiche package in polyfills.min.js:

  • version 3.x of Barbiche contains template-mb
  • version 2.x of Barbiche contains template-mb and classList.js

Barbiche API

Common usage

First, we create a Barbiche instance:

Now, barbiche is a factory function that expects the id string of a <template> element or a <template> element:

If no template is found, an unnamed empty <template> element is used so that subsequent operations fail silently.

If the template has an id attribute, Barbiche internally stores the template for later reuse:

Setting ids on your templates is strongly recommended.

Merging data into a Barbiche instance is done in this way:

The arguments of merge method are used to init the merge context: when Barbiche is looking for the value of an identifier, it searches first in obj_1, then in obj_2,..., then in obj_k. For example, you may consider that:

  • obj_1 is a plain JSON object that comes from your database
  • obj_2 is an object that contains functions and data specific to my-template
  • obj_3 is an object that contains functions and data common to all your templates

Some examples can be found here.

A DocumentFragment is returned that can be inserted in the main document:

When you are done with your merge operations, you can clean the barbiche store:

Barbiche objects

Barbiche instances expose a factory function for BBObj class:

Barbiche objects can be used to create a template from a string with an optional id:

Settings

Barbiche instance constructor accepts an optional settings object which defaults to:

  • delimiters is an array containing two distinct one character strings that will be used as delimiters for text and HTML insertion. Note that backslash character (\) is used for escaping delimiters and cannot be used as a delimiter. Some examples can be found here.
  • prefix is the word used to prefix Barbiche attributes. Internally, Barbiche uses the following attributes: bb-[if|else|alias|text|html|repeat|import|attr|class|global|inert]. If you need to use one of these attributes, you can set Barbiche prefix according to your needs.
  • document is the HTML document where Barbiche will search for templates.
  • destructive is a boolean that allows Barbiche to modify the HTML of the registered templates. (If false, Barbiche will use deep clones of the templates leaving your HTML untouched.)

Template description

<template>

Barbiche heavily relies on the great properties of the <template> element. An essential point of Barbiche is that you can wrap any html fragment of the template in a <template> element without changing the merge result. Sooner or later, you will want to set a Barbiche attribute between an element and its parent: just wrap the element in a <template> tag and set the attribute on this new tag.

Decorations

Barbiche templates are decorated with special attributes which are evaluated in this order:

  1. bb-if="expression" (and bb-else)
  2. bb-alias="expression"
  3. bb-repeat="expression (++|--)?"
  4. bb-import="expression"
  5. bb-attr="expression"
  6. bb-class="expression"

and use {{expression}} and {{{expression}}} for merging text and HTML, respectively.

An additional attribute bb-inert can be set on a <template> element so that Barbiche will consider it as any other non <template> element.

Expressions

Barbiche expressions support a subset of JavaScript:

  • boolean expressions: true, false, ||, &&, ==, !=, ===, !==, <=,>=, < ,> and !
  • null and undefined keywords: null and undefined
  • identifiers: my_text, my_html
  • arrays: [], [text, "string", 1.12]
  • function calls: my_function(obj), JSON.stringify(JSON.parse(str))
  • property accessors: object.property and object[computed property]
  • simple numbers: 1.2, 5, -7.58
  • strings: "double\"quote\"string" and 'simple\'quote\'string'
  • + operator

and a special constructor: expression: expression for building Barbiche object.

For convenience, any string can be used as an identifier by using backtick delimiters: `this-is not-a-valid-JS-identifier`.
Backticks inside a backticked identifier have to be escaped: \`.

Strings and identifiers support usual escape sequences (\n|\t|\r|\|\'|\"), hexadecimal and unicode escape sequences. Examples can be found here.

Text

Inserting text is done with {{expression}}.

  • if expression is a Barbiche object boolean: content, if boolean is true and if content is not null or undefined, a text node containing content.toString() is inserted
  • else, if expression is not null or undefined, a text node containing expression.toString() is inserted

A simple example:

will produce:

Other examples can be found here.

HTML

Inserting HTML is done with {{{expression}}}.

  • if expression is an instance of Node, it is inserted
  • else if expression is a Barbiche object boolean: content, if boolean is true and if content is not null or undefined, content.toString() is inserted as HTML
  • else, if expression is not null or undefined, expression.toString() is inserted as HTML

A simple example:

will produce:

Other examples can be found here.

Conditions

if an element is decorated with a bb-if="expression" attribute, its next sibling element (if it exists) may be decorated with an (empty) bb-else attribute. According to the truth value of expression, the element or its next sibling element is removed.

Note that no curly braces expression can be set between two consecutive sibling elements decorated with bb-if and bb-else and that a node cannot be decorated with both bb-if and bb-else attributes.

A simple example:

will produce:

Other examples can be found here.

Aliases

A bb-alias contains a Barbiche object or an array of Barbiche objects. For each object value: name, name is bound to value during the processing of the current subtree.

A simple example:

will produce:

Other examples can be found here.

Loops

A bb-repeat attribute contains an expression and ends with an optional -- or ++ keyword. The expression denotes a Barbiche object or an array of Barbiche objects which defines a set of nested loops. For each Barbiche object array: 'string', a loop is executed on array, binding each array item to 'string' and item index to '_string_'. A ++ ending keyword will insert merged items in natural order; -- will insert merged items in reverse order; no ending keyword is the same as ++.

For convenience, an undefined or null value for array is interpreted as an empty array: [].

Any object with a forEach method (e.g. Maps or Sets) can be used in loops.

A simple example:

will produce:

Other examples can be found here.

Imports

The bb-import attribute is reserved to <template> elements. The value of a bb-import attribute can be a template node, a template id or a Barbiche object. It is applied to the barbiche instance function. The returned template is then merged using current context and the current node is replaced with the merge result.

A simple example:

will produce:

Other examples can be found here.

Attributes

A bb-attr attribute contains a Barbiche object or an array of Barbiche objects. For each object value: name, if value and name are not undefined or null and if name.toString() is not empty, attribute name.toString() is set on the current node with value value.

A simple example:

will produce:

Other examples can be found here.

Classes

A bb-class attribute contains an expression or an array of expressions. For each expression:

  • if expression is a Barbiche object boolean: name, if boolean is true and if name is not null or undefined and if name.toString() is not empty, class name.toString() is added to the current element,
  • else if expression is not null or undefined and if expression.toString() is not empty, class expression.toString() is added to the current element.

A simple example:

will produce:

Other examples can be found here.

Inert attribute

A bb-inert attribute can be set on a <template> element so that Barbiche will consider the element as any other non <template> element.

Note that a <template> element can not be decorated with both bb-inert and bb-import attributes.

A simple example:

will produce:

Other examples can be found here.

Template polyfill caveats

Subdocument templates

Templates included in subdocuments (such as HTMLImports) need to be bootstrapped before being usable by calling:

Inherent limitations

Polyfilled templates are not as inert as native templates. For examples, scripts will be executed and images will be loaded.

In some rare situations, the HTML parser may break the template content. For example:

will give you an empty template. A workaround for this is to use a <script> tag:

and then register the template with: