stringtemplate

0.0.10 • Public • Published

stringtemplate

[ v0.0.10 ] Build Status

[ 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

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 and riot.js's render() method

    • $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

JSON License (Modified MIT)

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)

Package Sidebar

Install

npm i stringtemplate

Weekly Downloads

8

Version

0.0.10

License

JSON License (Modified MIT)

Last publish

Collaborators

  • dfkaye