stringtemplate
v0.0.10
Published
Minimalist Logic-less Templates in JavaScript
Downloads
56
Maintainers
Readme
stringtemplate
[ v0.0.10 ] [] (https://travis-ci.org/dfkaye/stringtemplate)
[ NOT STABLE ~ TOKEN SET STILL IN REVIEW ~ DOCS ARE INACCURATE ~ 18 OCT 2014 ]
You may view a presentation about this project on rawgit at https://rawgit.com/dfkaye/stringtemplate/master/shower/index.html.
You may read a very short version of this document at https://gist.github.com/dfkaye/9bf102b56063fd9628fb.
Minimalist Logic-less Templates in JavaScript
stringtemplate
adds a template()
method to String.prototype
and
Function.prototype
that act as a batch string#replace, using $token$
placeholders for values/objects and $#objectOrArray$
and $/objectOrArray$
tokens to demarcate iterable data with $.$
for array indexes or $.key$
for key-value data.
[ TODO ~ EXPAND THIS DESCRIPTION ]
Logic-less Templates
Terence Parr, The ANTLR Guy argues that templates are documents with "holes" and should contain no business logic. Instead, it is up to us who use template engines to provide data that is already modeled properly.
A template should merely represent a view of a data set and be totally divorced from the underlying data computations whose results it will display.
Read Parr's full argument in his paper on [Enforcing Strict Model-View Separation in Template Engines] (http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf)
Parr has implemented this strict separation in his own StringTemplate project for java (with ports for C#, Python).
stringtemplate ~ the JavaScript version
In this project, stringtemplate
is a JavaScript shim that adds the following
methods to native/built-in types:
[ NOT STABLE ~ TOKEN SET RE-DONE BUT STILL IN REVIEW ~ 18 OCT 2014 ]
String.prototype.template(data)
originally inspired by @krasimir's [js template engine in 20 15 lines] (http://krasimirtsonev.com/blog/article/Javascript-template-engine-in-just-20-line) and riot.js's [render() method] (https://github.com/muut/riotjs/blob/master/lib/render.js)
$placeholder$ ~ use value found at data.placeholder
$path.name$ ~ use value found at data.path.name
$#path.name$ ~ marks the start of an iteration ~ must have a matching end token, $/path.name$
$/path.name$ ~ marks the end of an iteration ~ must have a matching start $#path.name$ token
$.$ ~ inside an iteration, use object value at each index [0, 1, 2...]
$.key$ ~ inside an iteration, use value found at [index].name
$#.$ ~ start of a collection inside an iteration
$/.$ ~ end of a collection inside an iteration
$#.key$ ~ key-value collection inside an iteration
$/.key$ ~ end key-value collection inside an iteration
Function.prototype.template(data)
- originally inspired by @rjrodger's mstring
- returns
docstring
found by parsing contents between /*** and ***/ delimiters in function body and concatenates rows of text with newline character to preserve the docstring's vertical structure - returns empty string if no delimiters found
- returns docstring.template(data) if
data
argument specified, - otherwise returns the docstring unmodified.
- TODO (add note on how to configure uglify to allow comment delimiters while removing others)
- removes line comments found within delimiters
// so you can annotate lines
Examples
[ STILL IN PROGRESS ~ 18 OCT 2014 ]
values
var s = [
'<p>title: $title$</p>',
'<p>long name: $person.fullname$</p>'
].join('');
var d = {
title: 'value test',
person: {
fullname: 'my longer name'
}
};
var t = s.template(d);
var expected = '<p>title: value test</p><p>long name: my longer name</p>';
console.log(t === expected); // => true
simple array
var s2 = [
'<ul>',
'$#.$',
'<li>$.$</li>',
'$/.$',
'</ul>'
].join('');
var d2 = ['foo', 'bar', 'baz', 'quux'];
var t2 = s2.template(d2);
var expected = '<ul><li>foo</li><li>bar</li><li>baz</li><li>quux</li></ul>';
console.log(t2 === expected); // => true
complex data
var list = [
'<ul>',
'$#addresses$',
'<li>$.street$</li>',
'<li>$.city$, $.state$</li>',
'$/addresses$',
'</ul>'
].join('\n');
var t = list.template({
addresses: [
{ street: '123 fourth street', city: 'cityburgh', state: 'aa' },
{ street: '567 eighth street', city: 'burgville', state: 'bb' },
{ street: '910 twelfth street', city: 'villetown', state: 'cc' }
]
});
var expected = [
'<ul>',
'',
'<li>123 fourth street</li>',
'<li>cityburgh, aa</li>',
'',
'<li>567 eighth street</li>',
'<li>burgville, bb</li>',
'',
'<li>910 twelfth street</li>',
'<li>villetown, cc</li>',
'',
'</ul>'
].join('\n');
console.log(t === expected); // => true
combining template results
[ TODO ]
more interesting examples
[ TODO function#template ]
[ TODO css generator ]
[ TODO html generator ]
License
Tests
Tests are currently run with mocha
using the assert
, the qunit
ui and the
spec
reporter.
node
npm test
testem
npm run testem
Browser tests run fine with testem
, but mocha (on node) and testem do not play
as well together on a Windows laptop (like mine). YMMV.
rawgit
run browser-suite on rawgit (opens new tab|window)