Vash
Vash, the 60 billion double-dollar template-maker. Razor syntax, for JavaScript templates
Install / Use
/learn @kirbysayshi/VashREADME
Vash
"... the 60 billion double-dollar template-maker!" ~ The previous README, and no one else, ever.
Vash is a template engine that offers a swift flow between code and content using Razor Syntax <sup id="fnref:razor-ms"> <a rel="footnote" href="#fn:razor-ms">1</a> </sup>. This document <sup id="fnref:this-doc"> <a rel="footnote" href="#fn:this-doc">2</a> </sup> is intended for users of Vash, and also serves as a reference for Vash's implementation of Razor Syntax.
- Features
- Syntax Example
- Quick Start
- Playground
- Syntax
- Configuration
- Template Options
- Helper System
- Built-in Helpers
- Layout Helpers
- Compiled Helpers
- Buffer API
- Precompiling Templates
- Vash Runtime (Browser)
- Compile-time API
- Runtime API
- vash(1)
- Contributing / Building
- Getting Help
- Special Thanks
- License
<a name="features"></a>Features
- Mix code and content without ugly delineators, like
<?,<%, or{{. - No new language to learn: Vash is just HTML-aware JavaScript.
- Great with markup, but can be used with nearly any other language as well (even Markdown!).
- Helpers API allows for extensibility and meta programming.
- Works in the browser or in node.
- Comes with a Jade-inspired layout engine (block, include, extend, append/prepend), which even works in the browser.
<a name="syntax-example"></a>Syntax Example
<p>How are you @model.name? Today is a sunny day on the planet Gunsmoke.</p>
<ul class="@(model.active ? 'highlight' : '')">
@model.forEach(function(m){
<li>@m.name</li>
})
</ul>
<a name="quick-start"></a>Quick Start
<a name="nodejs"></a>nodejs
var vash = require('vash');
var tpl = vash.compile('<p>I am a @model.t!</p>');
var out = tpl({ t: 'template' });
// <p>I am a template!</p>
<a name="express"></a>express
Check out vash-express-example for a full example of hooking up vash as a view engine for express 3. But it's basically as simple as:
var express = require('express');
var app = express();
app.set('view engine', 'vash');
More information is also available in the [Layout Helpers][] sections.
<a name="browser---vanilla"></a>Browser - Vanilla
<script type="text/javascript" src="build/vash.js"></script>
var tpl = vash.compile( '<p>I am a @model.t!</p>' );
document.querySelector('#content').innerHTML = tpl({ t: 'template' });
But you should probably be precompiling your templates. See [Precompiling Templates][] for more info. Then you can just include the Vash runtime instead of the entire compiler.
<a name="browser---browserify-et-al"></a>Browser - Browserify et al
Just require Vash, and compile. If you want something fancier, try vashify! Then you can directly require any .vash file and it will be resolved as compiled template:
var tpl = require('my-awesome-template.vash');
document.querySelector('#content').innerHTML = tpl({ t: 'template' });
<a name="browser---requirejs"></a>Browser - RequireJS
RequireJS support has been recently dropped. However Vash does support CJS environments, so as long as you configure RequireJS to consume Vash as a CJS project (including node_modules resolution), everything should work.
<a name="playground"></a>Playground
Vash now has a playground of sorts at CodePen.io. It uses the current version of vash.js from the build folder. Fork it to test your own template ideas!
<a name="syntax"></a>Syntax
For the following examples, assume a model is passed into the compiled function. If a model is explicitly defined, it will appear as:
// model = { what: 'hello!' }
<a name="the-transition-character"></a>The Transition Character: @
Vash uses the @ symbol to transition between code and markup. To escape and print a literal @, use a double @, like this: @@.
<a name="expressions"></a>Expressions
The most basic usage of Vash is an implicit expression. Vash is smart enough to know what's valid JS and what's not, and can usually do what you want it to do. An expression is an @ followed by a valid JS identifier. This is then interpolated automatically.
input:
// model = { what: 'hello!' }
<p>@what</p>
output:
<p>hello!</p>
The model comment is just to show that the object passed into the compiled template contains a key that matches the expression.
To allow for the fastest render time possible, Vash by default requires the model to be addressed explicitly. This is to avoid using a with statment in the compiled template, which is approximately 25 times slower. The above example then becomes:
input:
<p>@model.what</p>
output:
<p>hello!</p>
As you can see, the output is exactly the same. The name used to reference the model is configurable via [vash.config.modelName][]. Typical values are model and it.
<a name="advanced-expressions"></a>Advanced Expressions
Vash typically knows when an expression ends, even when the expression is complex. For example:
input:
<p>@model.what().who[2]('are you sure')('yes, it\'s ok')( model.complex ? 'FULL POWER' : '' )</p>
This will work just fine, assuming you have a model that actually contains that complexity! I hope you don't, and if so, I feel bad.
Callbacks work as well:
input:
// model = ['a', 'b']
@model.forEach(function(item){
<li>@item</li>
})
outputs:
<li>a</li><li>b</li>
Vash also knows the difference between JS dot notation and a period.
input:
// model = { description: 'living' }
<p>Plants are @model.description.</p>
output:
<p>Plants are living.</p>
And empty brackets, because they're not valid JS:
input:
// model = { formName: 'addresses' }
<input type="text" name="@model.formName[]" />
output:
<input type="text" name="addresses[]" />
Email addresses, to an extent, are fine as well. Vash makes a trade-off. It uses the following regex to validate an email address:
/^([a-zA-Z0-9.%]+@[a-zA-Z0-9.\-]+\.(?:ca|co\.uk|com|edu|net|org))\b/
Email addresses can actually contain many more valid characters, and are really hard to validate. Vash can handle a typical email address with ease:
input:
<a href="mailto:vash@planetgunsmoke.com">Email Me</a>
output:
<a href="mailto:vash@planetgunsmoke.com">Email Me</a>
If you have a complex email address that confuses Vash, then you should use an explicit expression instead.
<a name="explicit-expressions"></a>Explicit Expressions
An explicit expression is simply an expression that, instead of bein




