#Script aims to be a familiar and expressive dynamic language for scripting .NET Apps, that is optimal at generating text, especially HTML where it's pre-configured with the HTML Page Format and HTML Scripts but unlike C#'s Razor can support multiple pluggable page formats which can be used for generating any kind of text.

For maximum familiarity #Script uses JavaScript Expressions that for increased readability and expressiveness supports being used within Template Expressions which like Vue.js filters, and Angular's Template Expressions lets you use the | pipe operator to chain the return values of methods into subsequent methods from left-to-right. For statements #Script adopts the familiar Handlebars-like Script Blocks that is also popular among HTML templating engines.

Effectively #Script lets you use the same familiar JS language for server HTML rendering as you would do in client-side rendering of Single Page Apps despite it binding natively to C# objects and calling C# methods behind-the-scenes.

Mustache expressions

Like Vue/Angular Templates, only expressions inside mustaches are evaluated, whilst everything outside are emitted as-is:

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

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

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

Methods can be chained

Methods 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 method on the right and the output of that is passed as the input of the next method in the chain and so on:

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

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:


Strings can be defined 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

Template Expressions 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 methods to enable LINQ-like queries. You can use fat arrows => immediately after methods 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 #Script, we've also given them special wrist-friendly syntax where you can add a colon at the end of the method 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 method to immediately short-circuit evaluation, e.g: {{ end | now | dateFormat }}

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

made with by ServiceStack