DubStash is a fast, lightweight and simple semantic template engine for HTML.
<script src="dubstash.min.js"></script>
Details...
{{placeholders}}
for values that will be substituted at runtime.{{placeholders}}
.{{placeholders}}
is escaped for safe use in HTML, unless you use a{{{triple-stash}}}
(not shown).// Define the template. You normally won't do this using Javascript. Instead you can use the new
// HTML5 <template> tag, or put your templates inside <script type="text/dubstash">...</script>,
// and assign the contents to a Javascript variable using the script tag's innerHTML property.
var template = '<ul><li>My name is {{name}}.</li>' +
'<li>I live in {{address.city}}.</li>' +
'<li>My favourite cartoon is {{cartoon}}.</li></ul>';
// Generate a rendering function that can be used multiple times with different data.
var render = DubStash.compile(template);
// Define some example data objects.
var person1 = {
name: 'John Smith',
address: {
city: 'Cardiff'
},
cartoon: 'Calvin & Hobbes'
};
var person2 = {
name: 'Fred Bloggs',
address: {
city: 'Swansea'
},
cartoon: 'Tom & Jerry'
};
// Render the template with different data.
var output1 = render(person1);
var output2 = render(person2);
The value of output1
is:
<ul>
<li>My name is John Smith.</li>
<li>I live in Cardiff.</li>
<li>My favourite cartoon is Calvin & Hobbes.</li>
</ul>
<!-- Linebreaks and indents added for clarity -->
The value of output2
is:
<ul>
<li>My name is Fred Bloggs.</li>
<li>I live in Swansea.</li>
<li>My favourite cartoon is Tom & Jerry.</li>
</ul>
<!-- Linebreaks and indents added for clarity -->
{{name}}
is used twice, but the second instance refers to a different person.
../
../../
etc.forEach
var template = '<p>These are the people that {{name}} invited:</p>' +
'<ul>{{foreach invitees}}<li>{{name}} (invited by {{../../name}})</li>{{end foreach}}</ul>';
var render = DubStash.compile(template);
var person = {
name: 'John Smith',
invitees: [
{name: 'Fred Bloggs'},
{name: 'Jack Jackson'},
{name: 'Mary Black'}
]
};
var output = render(person);
The value of output
is:
<p>These are the people that John Smith invited:</p>
<ul>
<li>Fred Bloggs (invited by John Smith)</li>
<li>Jack Jackson (invited by John Smith)</li>
<li>Mary Black (invited by John Smith)</li>
</ul>
<!-- Linebreaks and indents added for clarity -->
{{if propertyName}} ... {{else}} ... {{endif}}
for including text conditionally.false
, so you can easily test whether a collection hasvar template = '<p>Dear {{if isMale}}Sir{{else}}Madam{{endif}},</p>' +
'{{if itemsOrdered}}'
'<p>These are the items you ordered:</p>' +
'<ul>' +
'{{foreach itemsOrdered}}<li>{{name}}</li>{{end foreach}}' +
'</ul>' +
'{{else}}' +
'<p>You have not ordered anything recently.</p>' +
'{{end if}}';
var render = DubStash.compile(template);
var recipient = {
gender: 'f',
isMale: function(){
return recipient.gender === 'm';
},
itemsOrdered: [
{name: 'Grand Piano'},
{name: 'Violin'},
{name: 'Flute'}
]
};
var output = render(recipient);
The value of output
is:
<p>Dear Madam,</p>
<p>These are the items you ordered:</p>
<ul>
<li>Grand Piano</li>
<li>Violin</li>
<li>Flute</li>
</ul>
<!-- Linebreaks and indents added for clarity -->
// 'bestName' is a template that writes out the best name to use for greeting a person:
DubStash.registerGlobalTemplate('bestName',
'{{if nickName}}{{nickName}}{{else}}{{firstName}}{{end if}}');
// Define the text of a generic letter.
var renderLetter = DubStash.compile('<p>Dear {{bestName}},</p>');
var person1 = {
firstName: 'William',
lastName: 'Smith',
nickName: 'Bill'
};
var person2 = {
firstName: 'Frederick',
lastName: 'Bloggs'
};
var output1 = renderLetter(person1);
var output2 = renderLetter(person2);
The value of output1
is:
<p>Dear Bill,</p>
The value of output2
is:
<p>Dear Frederick,</p>
{{blurb2 /r}}
In the global templates example, the greeting template does not handle a case where we don't know a person's first name or nickname. Let's build a template that makes up for that deficiency.
// 'bestName' is a template that writes out the best name to use for greeting a person:
DubStash.registerGlobalTemplate('bestName',
'{{if nickName}}{{nickName}}{{else}}{{firstName}}{{end if}}');
// Define the text of a generic letter. If we don't know a person's name, say 'Sir'.
var renderLetter = DubStash.compile(
'<p>Dear {{if bestName}}{{bestName}}{{else}}Sir{{end if}},</p>');
var person3 = {
lastName: 'Heisenberg'
};
var output3 = renderLetter(person3);
The value of output3
is:
<p>Dear Sir,</p>
DubStash.compile()
step.// Typically you would do this in Node, where you can save the precompiled functions without having
// to manually copy/paste them into a .js source file.
var DubStash = require('./dubstash.js');
// 'bestName' is a template that writes out the best name to use for greeting a person:
DubStash.registerGlobalTemplate('bestName',
'{{if nickName}}{{nickName}}{{else}}{{firstName}}{{end if}}');
var globalsSource = DubStash.precompileGlobalTemplates();
var template = 'My name is {{bestName}}.';
var rendererSource = DubStash.precompile(template);
// Build the output which should be saved as a JS file.
var output = globalsSource + '\n';
output += 'var render = ' + rendererSource;
...
The resulting output will look like this:
DubStash.G('bestName', function( ... ){ ... });
var render = function( ... ){ ... }
Your HTML file needs to use the DubStash script. Use the distributable version dubstash.min.js.
<html>
<head>
...
<script src="dubstash.min.js"></script>
...
</head>
<body>
...
</body>
</html>
DubStash is compiled and minified using Google Closure Compiler. The following command line does it:
npm run build
npm test