virtual-stache

template engine for creating virtual trees.

Usage no npm install needed!

<script type="module">
  import virtualStache from 'https://cdn.skypack.dev/virtual-stache';
</script>

README

virtual-stache

template engine for creating virtual trees.

See virtual-stachify for the browserify transform.

example

given this template:

<h1>{title}</h1>
<ul>
  {#fruits}<li>{name}</li>{/fruits}
</ul>

produce rows of compiled functions for each top-level node:

var compile = require('virtual-stache');
var fs = require('fs');

var dup = compile();
fs.createReadStream(__dirname + '/layout.html')
  .pipe(dup);

dup.on('data', function (render) {
  console.log(String(render));
});

then we can call the generated function in a Template context and create a virtual-dom VTree:

var Template = require('virtual-stache/template');
var createElement = require('virtual-dom/create-element');

dup.on('data', function (render) {
  var state = {
    fruits: [
      { name: 'kiwi '},
      { name: 'mango '}
    ]
  };
  var opts = {
    Node: require('virtual-dom/vnode/vnode'),
    Text: require('virtual-dom/vnode/vtext')
  };
  var tree = render.call(new Template, state, opts);
  var rootNode = createElement(tree);
  document.body.appendChild(rootNode);
});

 api

var compile = require('virtual-stache');

var pipeline = compile()

Returns a pipeline duplex stream that takes stache input and produces rows of output. The output rows are pre-compiled functions that can be evaluated for rendering and have the following signature:

function render (state, options, constructor)

You can pass a constructor to create an execution context at runtime, or use call() to bind an existing one:

var tpl = new Template();
render.call(tpl, state, options);

template

virtual-stache provides a virtual-dom compatible Template that can be used at runtime to create virtual trees.

var Template = require('virtual-stache/template');

However, Template is not bundled with virtual-dom, so you need to provide VNode and VText explicitly. This is done by passing Node and Text in options object.

var options = {
  Node: require('virtual-dom/vnode/vnode'),
  Text: require('virtual-dom/vnode/vtext')
};
var tree = render(state, options, Template);

options object must have following properties:

  • Node is a virtual node constructor that implements the VNode interface
  • Text is a virtual node contructor that implements the VText interface

The only optional property of options is escape, when enabled, it escapes html entities in strings to be safe for use in text nodes; by default nothing is escaped.

Also note that, Template always sets parsed attributes in properties.attributes object. You can override this behaviour if you need something else.

compiler pipeline

There is an internal labeled-stream-splicer pipeline with these labels:

  • parse - tokenize and parse stache templates
  • pack - wrap the parse tree as a Function

You can call compile().get() with a label name to get a handle on a stream pipeline that you can push(), unshift(), or splice() to insert your own transform streams.

stache

virtual-stache uses tokenize-stache to parse templates and supports a minimal set of mustache spec that covers variable interpolation and sections only. Currently stache tags in attributes are not supported.

variables

template:

<h1>{name}</h1>

state:

{
  "name": "Paul Atreides"
}

output:

<h1>Paul Atreides</h1>

sections

A section property can be an object, boolean or an array that will be iterated.

template:

<ul>
  {#fruits}
  <li>
    {name}
    {#vitamins}<span>{name}</span>{#vitamins}
  </li>
  {/fruits}
</ul>

state:

{
  "fruits": [
    {
      "name": "Kiwi",
      "vitamins": [ { "name": "B-6" }, { "name": "C" } ]
    },
    {
      "name": "Mango"
    }
  ]
}

output:

<ul>
  <li>
    Kiwi
    <span>B-6</span><span>C</span>
  </li>
  <li>
    Mango
  </li>
</ul>

todo

See issues.

license

mit