The syntax is inspired by and it most cases compatible with Vue.js filters, with the goal being you can use the same common language to implement server rendering with ServiceStack Templates as you would do in client-side rendering of Single Page Apps using Vue filters. With this in mind, the syntax within mustaches is compatible with JavaScript where you can use native JS data structures despite it creating C# objects and calling C# methods behind-the-scenes.

Mustache expressions

Just like Vue filters, only expressions inside mustaches are evaluated, everything outside mustaches are emitted as-is:

Which calls the upper default filter function where the argument on the left-side of the "pipe" symbol is passed as the first argument to the filter which is implemented as:

public string upper(string text) => text?.ToUpper();

This can also be rewritten without the "pipe" symbol by calling the filter with an argument instead:

Filters can be chained

Filters are chained from left-to-right where the value on the left side of the "pipe" symbol is passed as the first argument in the filter on the right and the output of that is passed as the input of the next filter in the chain and so on:

Filters can also accept additional arguments which are passed starting from the 2nd argument since the first argument is the value the filter is called with. E.g. here are the implementations for the substring and padRight default filters:

public string substring(string text, int startIndex) => text.SafeSubstring(startIndex);
public string padRight(string text, int totalWidth, char padChar) => text?.PadRight(totalWidth, padChar);

JavaScript literal notation

You can use the same literal syntax used to define numbers, strings, booleans, null, Objects and Arrays in JavaScript within templates and it will get converted into the most appropriate .NET Type, e.g:

ES6 Shorthand notation is also supported where you can use the argument name as its property name in a Dictionary:


As strings are prevalent in Templates, you can define them using single quotes, double quotes, prime quotes or backticks:

Strings can also span multiple lines.

Template Literals

Backticks strings implement JavaScript's Template literals which can be be used to embed expressions:
The example above also shows the difference in escaping where Template literals evaluate escaped characters whilst normal strings leave \ backspaces unescaped.

Shorthand arrow expression syntax

Filters have full support for JavaScript expressions but doesn't support statements or function declarations although it does support JavaScript's arrow function expressions which can be used in functional filters to enable LINQ-like queries. You can use fat arrows => immediately after filters to define lambda's with an implicit (it => ...) binding, e.g:

This is a shorthand for declaring lambda expressions with normal arrow expression syntax:

Using normal lambda expression syntax lets you rename lambda parameters as seen in the map(x => ...) example.

Special string argument syntax

As string expressions are a prevalent in Templates, we've also given them special wrist-friendly syntax where you can add a colon at the end of the filter name which says to treat the following characters up until the end of the line or mustache expression as a string, trim it and convert '{' and '}' chars into mustaches. With this syntax you can write:

and it will be rewritten into its equivalent and more verbose form of:

SQL-like Boolean Expressions

To maximize readability and intuitiveness for non-programmers, boolean expressions can also adopt an SQL-like syntax where instead of using &&, || or == operator syntax to define boolean expressions you can also use the more human-friendly and, or and = alternatives:

Include Raw Content Verbatim

Use #raw blocks to ignore evaluating expressions and emit content verbatim. This is useful when using a client Handlebars-like templating solution like Vue or Angular templates where expressions need to be evaluated with JavaScript in the browser instead of on the Server with Templates:

Multi-line Comments

Any text within {{#noop}} ... {{/noop}} block statements are ignored and can be used for temporarily removing sections from pages without needing to delete it.

Everything within multi-line comments {{‌* and *‌}} is ignored and removed from the page.

An alternative way to temporarily disable an expression is to prefix the expression with the end filter to immediately short-circuit evaluation, e.g: {{ end | now | dateFormat }}

See Ignoring Pages for different options for ignoring entire pages and templates.

made with by ServiceStack