DocumentEngine expressions are the basic unit of a DocumentEngine template. You can use them alone in a {{mustache}}
, pass
them to a DocumentEngine helper, or use them as values in hash arguments.
DocumentEngine expressions are some contents enclosed by double curly braces {{}}
. In the below template, firstname
is a
variable that is enclosed by double curly braces, which is said to be an expression.
<p>{{firstname}} {{lastname}}</p>
If the below input object is applied to the template
{
firstname: "Yehuda",
lastname: "Katz",
}
Expressions are compiled to produce the output as follows:
<p>Yehuda Katz</p>
DocumentEngine expressions can also be dot-separated paths.
{{person.firstname}} {{person.lastname}}
This expression looks up the person
property in the input object and in turn looks up the firstname
and lastname
property within the person
object.
Pass the below input object to the template
{
person: {
firstname: "Yehuda",
lastname: "Katz",
},
}
Output will be generated as below
Yehuda Katz
DocumentEngine also supports a deprecated /
syntax, so you could write the above template as:
{{person/firstname}} {{person/lastname}}
Some helpers like #with
and #each
allow you to dive into nested objects. When you include ../
segments in your
path, DocumentEngine will change back into the parent context.
{{#each people}}
{{../prefix}} {{firstname}}
{{/each}}
Even though the name is printed while in the context of a comment, it can still go back to the main context (the root-object) to retrieve the prefix.
WARNING
The exact value that ../
will resolve to varies based on the helper that is calling the block. Using ../
is only
necessary when context changes. Children of helpers such as {{#each}}
would require the use of ../
while children of
helpers such as {{#if}}
do not.
{{permalink}}
{{#each comments}}
{{../permalink}}
{{#if title}}
{{../permalink}}
{{/if}}
{{/each}}
In this example all of the above reference the same prefix value even though they are located within different blocks.
This behavior is new as of DocumentEngine 4; the
release notes
Identifiers may be any unicode character except for the following:
Whitespace !
"
#
%
&
'
(
)
*
+
,
.
/
;
<
=
>
@
[
\
]
^
`
{
|
}
~
In addition, the words true
, false
, null
and undefined
are only allowed in the first part of a path expression.
To reference a property that is not a valid identifier, you can use segment-literal notation, [
. You may not include a
closing ]
in a path-literal, but all other characters are allowed.
JavaScript-style strings, "
and '
, may also be used instead of [
pairs.
{{!-- wrong: {{array.0.item}} --}}
correct: array.[0].item: {{array.[0].item}}
{{!-- wrong: {{array.[0].item-class}} --}}
correct: array.[0].[item-class]: {{array.[0].[item-class]}}
{{!-- wrong: {{./true}}--}}
correct: ./[true]: {{./[true]}}
In DocumentEngine, the values returned by the {{expression}}
are HTML-escaped. Say, if the expression contains &
, then
the returned HTML-escaped output is generated as &
. If you don't want DocumentEngine to escape a value, use the
"triple-stash", {{{
:
In the below template, you can learn how to produce the HTML escaped and raw output.
raw: {{{specialChars}}}
html-escaped: {{specialChars}}
Pass the special characters to the template
{ specialChars: "& < > \" ' ` =" }
Expressions enclosed by "triple-stash" ({{{
) produce the raw output. Otherwise, HTML-escaped output is generated as
below.
raw: & < > " ' ` =
html-escaped: & < > " ' ` =
Helpers can be used to implement functionality that is not part of the DocumentEngine language itself.
A helper can be registered at runtime via DocumentEngine.registerHelper
, for example in order to uppercase all characters
of a string.
DocumentEngine.registerHelper('loud', function (aString) {
return aString.toUpperCase()
})
A DocumentEngine helper call is a simple identifier, followed by zero or more parameters (separated by a space). Each parameter is a DocumentEngine expression that is evaluated exactly the same way as described above in "Basic Usage":
{{firstname}} {{loud lastname}}
In this case, loud
is the name of a helper, and lastname
is a parameter to the helper. The template will uppercase
the lastname
property of the input:
{
firstname: "Yehuda",
lastname: "Katz",
}
Yehuda KATZ
When your helper returns an instance of DocumentEngine.Safestring
the return-value is not escaped, even if the helper is
called with {{
instead of {{{
. You have to take care that all parameters are escaped properly using
DocumentEngine.escapeExpression
.
DocumentEngine.registerHelper("bold", function(text) {
var result = "<b>" + DocumentEngine.escapeExpression(text) + "</b>";
return new DocumentEngine.SafeString(result);
});
Let us see another example of helpers with two parameters
{{link "See Website" url}}
In this case, DocumentEngine will pass the link helper two parameters: the String See Website
and the value of
people.url
from the below provided input people
object.
{ url: "https://yehudakatz.com/" }
The helper function link
is used to generate a hyperlink as described in the script.
DocumentEngine.registerHelper("link", function(text, url) {
var url = DocumentEngine.escapeExpression(url),
text = DocumentEngine.escapeExpression(text)
return new DocumentEngine.SafeString("<a href='" + url + "'>" + text +"</a>");
});
We will obtain the output using the input parameters
<a href='https://yehudakatz.com/'>See Website</a>
In the above example, You could use the exact same helper with dynamic text based on the value of people.text
:
{{link people.text people.url}}
{
people: {
firstname: "Yehuda",
lastname: "Katz",
url: "https://yehudakatz.com/",
text: "See Website",
},
}
Helper calls may also have literal values passed to them either as parameter arguments or hash arguments. Supported
literals include numbers, strings, true
, false
, null
and undefined
:
{{progress "Search" 10 false}}
{{progress "Upload" 90 true}}
{{progress "Finish" 100 false}}
DocumentEngine provides additional metadata, such as Hash arguments, to helpers as a final parameter.
{{link "See Website" href=person.url class="person"}}
In that template,the final parameter href=people.url class="people"
are hash arguments sent to the helper.
The keys in hash arguments must each be simple identifiers, and the values are DocumentEngine expressions. This means that values can be simple identifiers, paths, or Strings.
If we pass the below input to the template, the value of person.url
can be obtained from the person
object.
{
person: {
firstname: "Yehuda",
lastname: "Katz",
url: "https://yehudakatz.com/",
},
}
As described in the helper script below, the hash arguments can be obtained from the last parameter options
for
further processing within the helper.
DocumentEngine.registerHelper("link", function(text, options) {
var attributes = [];
Object.keys(options.hash).forEach(key => {
var escapedKey = DocumentEngine.escapeExpression(key);
var escapedValue = DocumentEngine.escapeExpression(options.hash[key]);
attributes.push(escapedKey + '="' + escapedValue + '"');
})
var escapedText = DocumentEngine.escapeExpression(text);
var escapedOutput ="<a " + attributes.join(" ") + ">" + escapedText + "</a>";
return new DocumentEngine.SafeString(escapedOutput);
});
The output of above helper is generated as below
<a class="person" href="https://yehudakatz.com/">See Website</a>
DocumentEngine also offers a mechanism for invoking a helper with a block of the template. Block helpers can then invoke that block zero or more times with any context it chooses.
If a helper is registered by the same name as a property of an input object, the helper has priority over the input
property. If you want to resolve the input property instead, you can prefix its name with ./
or this.
(or the
deprecated this/
)
helper: {{name}}
data: {{./name}} or {{this/name}} or {{this.name}}
{ name: "Yehuda" }
DocumentEngine.registerHelper('name', function () {
return "Nils"
})
DocumentEngine offers support for subexpressions, which allows you to invoke multiple helpers within a single mustache, and pass in the results of inner helper invocations as arguments to outer helpers. Subexpressions are delimited by parentheses.
{{outer-helper (inner-helper 'abc') 'def'}}
In this case, inner-helper
will get invoked with the string argument 'abc'
, and whatever the inner-helper
function
returns will get passed in as the first argument to outer-helper
(and 'def'
will get passed in as the second
argument to outer-helper
).
Template whitespace may be omitted from either side of any mustache statement by adding a ~
character by the braces.
When applied all whitespace on that side will be removed up to the first DocumentEngine expression or non-whitespace
character on that side.
{{#each nav ~}}
<a href="{{url}}">
{{~#if test}}
{{~title}}
{{~^~}}
Empty
{{~/if~}}
</a>
{{~/each}}
with this context:
{
nav: [{ url: "foo", test: true, title: "bar" }, { url: "bar" }];
}
results in output sans newlines and formatting whitespace:
<a href="foo">bar</a><a href="bar">Empty</a>
This expands the default behavior of stripping lines that are "standalone" helpers (only a block helper, comment, or partial and whitespace).
{{#each nav}}
<a href="{{url}}">
{{#if test}}
{{title}}
{{^}}
Empty
{{/if}}
</a>
{{~/each}}
will render
<a href="foo">
bar
</a>
<a href="bar">
Empty
</a>
DocumentEngine content may be escaped in one of two ways, inline escapes or raw block helpers. Inline escapes created by
prefixing a mustache block with \
. Raw blocks are created using {{{{
mustache braces.
\
{{{{raw}}}}
{{escaped}}
{{{{/raw}}}}
Raw blocks operate in the same manner as other block helpers with the distinction of the child content is treated as a literal string.