A quick cheatsheet of the tempura template syntax.
The tempura template syntax is very similar to the Handlebars or Mustache template syntax.
In fact, they're more similar than they are different!
General Notice Throughout this document, you'll notice that most examples include HTML tags or produce HTML output. This is done only because HTML is a common target. Tempura templates do not need to use or produce HTML content – it only cares about its own template syntax!
Templates are (hopefully!) an easier way to write and maintain view logic. Nearly all template engines, including tempura
, parse your template files and generate a function (per template) that includes all your view logic and desired output.
Each of these functions is valid JavaScript and is waiting to accept an input
object. Together, the input data and the render function produce the expected output.
Values can be printed by wrapping content with the {{
and }}
characters. These can appear anywhere within your template, and typically reference a variable name, although they could wrap any value.
When the template is evaluated, these expressions are replaced. For example:
rendered with the input:
{ name: 'world' }
produces the result:
<p>Hello, world!</p>
Expression values can reference any defined variables. In this example, name
was a simple string, but it could have been an object, an Array, or anything else!
For example, this template:
with this input object:
{
items: ["foo", "bar", "baz"]
}
produces this output:
<p>Items left: 3</p>
By default, all expressions are HTML-escaped. For example, if the value contains the "
, &
, or <
characters, they'd be encoded into the "
, &
, and <
sequences, respectively.
Note: The HTML-escape function can be customized via the
escape
option.
It's generally recommended to use HTML-escaping unless you're certain that the expression's value does not contain any HTML characters; eg, it's a number or you just constructed it via #var
.
To disable HTML-escaping for a value, you must use the triple-curly syntax; for example {{{ value }}}
.
When the triple-curly is used, the raw value is printed as is.
<!-- output -->
escaped: a & b " c < d
raw: a & b " c < d
It's generally recommended to include comments within your templates, especially as their complexity grows!
Template comments will never appear in the rendered output. However, HTML comments are kept.
The tempura syntax comes with few (but powerful) template helpers!
Unlike value expressions, template helpers – or "blocks" – always use double-curly tags. This is because they're not values, so there's no HTML-escape vs raw dilemma. The shorter, double-curly tag is used as a convenience.
Note: You may define your own helpers! See Custom Blocks for more detail.
A template needs to declare what variables it expects to receive. In several UI frameworks, this is generally referred to as defining your "props". At the parser level, this prepares the Compiler
so that it won't throw any Uncaught ReferenceError
s during execution.
Note: You should hoist common variables via
options.props
to avoid repetitive#expect
declarations.
You may declare multiple variables within the same #expect
block. You may also have multiple #expect
blocks in the same file:
In this snippet, the rest of the template file may safely use the name
, foo
, bar
, hello
, title
, and todos
variables. If any of these variables had been referenced without being declared (either thru #expect
or options.props
), then a ReferenceError
error would have been thrown at runtime.
This is because tempura prefers to be strict by default. If, however, you would prefer to relax this condition, you may enable the loose
option during any tempura.compile
or tempura.transform
calls.
You may define new variables within your template and reference them throughout the file. Normal JavaScript scoping rules apply.
These inline variables can evaluate any JavaScript and can reference other template variables.
Only one variable can be defined per #var
block. You may have any number of #var
blocks in your template:
Your control flow helpers!
Just like JavaScript, use of #elif
(short for else if
) and #else
are optional, but must always be associated with and follow an #if
opener. Parenthesis around the #if
and #elif
conditions are optional:
All #if
blocks must be terminated by an /if
block.
The #each
block loops over an Array, passing through each value and index to the template expression(s) within the block.
All #each
blocks must be terminated by an /each
block.