Introduction

Handlebars

Brightspot’s templating language is significantly based on Handlebars, a platform for building semantic templates. Handlebars provides a convenient method for coding standard HTML and incorporating the results of functions.

<p>{{firstName}}</p>

In the previous snippet, there are standard open-paragraph and close-paragraph tags. The “handlebars” placeholder {{firstName}} indicates that the result of a function firstName appears within the paragraph tags.

Handlebars is particularly useful for Brightspot development. On the production backend, a Java implementation evaluates the Handlebars placeholders and injects the values into the templates at run time. On the development frontend, a Node.js implementation also evaluates the Handlebars placeholders and injects values into the templates at run time. These two implementations, Java and Node.js, ensure Styleguide is truly a standalone application for web development: frontend engineers and designers prepare the HTML and CSS code, while backend developers independently prepare the data models and processing. The only required coordination between the two groups is maintaining the name of the placeholders.

BEM

The block-element-modifier (BEM) methodology addresses the problem of reusing and maintaining identifiers for HTML markup and CSS styling.

Consider the following HTML snippet:

<div class="biography">
    <p class="firstname">Bill</p>
    <p class="lastname">Shakespeare</p>
</div>

The corresponding CSS is as follows:

firstname {font-size: 12px;}
lastname {font-size: 14px;}

The problem with this approach is that if the class firstname and lastname appear in other contexts, you may want to typeset them differently, such as with underline or boldface. This leads to combinators of CSS selectors (siblings, children, descendants), such as in the following snippet.

biography > firstname {font-size: 12px;}
biography > lastname {font-size: 14px;}

Combinators can introduce complex stylesheets, and can increase the maintenance and debugging effort.

A better approach is to use the block-element-modifier (BEM) methodology, in which identifiers flow down from one element to another.

<div class="biography">
    <p class="biography-firstname">Bill</p>
    <p class="biography-lastname">Shakespeare</p>
</div>

In the previous snippet, the child <p> elements have class names that incorporate the parent <div>’s class name.

The corresponding CSS is as follows:

biography-firstname {font-size: 12px;}
biography-lastname {font-size: 14px;}

This implementation promotes modularity: if the block appears inside another <div class="player">, the BEM methodology requires adding two more CSS selectors with only the incremental styling for the enclosing <div>.

<div class="player">
    <div class="biography">
        <p class="biography-firstname">Adam</p>
        <p class="biography-lastname">Gilchrist</p>
    </div>
</div>

The corresponding CSS is as follows:

1
2
3
4
biography-firstname {font-size: 12px;}
biography-lastname {font-size: 14px;}
player-biography-firstname {font-weight: bold;}
player-biography-lastname {font-weight: bold;}

In the previous snippet, lines 3–4 apply incremental styling for firstname and lastname within a tag <div class="player">.

See also: