Spectrum

Spectrum Template Syntax

To get started with Spectrum to try the different bits of syntax, see Getting Started with Micro and Spectrum.

Expression Tags - Output Variable or Expression

An expression tag inserts the result of a JavaScript expression into the output:

Hello <%= user.name %>.

The content will have HTML entities (<, >, " and &) escaped by default to make it suitable for inserting content into an HTML page.

Code Tags - Embed JavaScript in a Template

Code tags allow you to insert larger chunks of JavaScript code:

<%
    var pi = 3.14159;
%>

Control structures can span multiple code tags, so you can use this feature to embed content within conditionals and loops. However, the following feature is often more convenient for this:

Code Lines - Embed Lines of JavaScript in a Template

Lines of javascript can be mixed with the output by prefixing each line with a colon:

: if (validation_error) {
    <p class="error">An error has occurred.</p>
: }

Multiple lines run together, i.e. this works:

: if (validation_error)
: {
    <p class="error">An error has occurred</p>
: }

The initial colon must have nothing on the line before it apart from whitespace. Neither this whitespace nor the trailing newline are included in the template output.

Methods - Reuse Within a Template

When a Spectrum template is rendered, an instance of it is created and the main content specified within it is what is returned. In addition to this, you can define and use smaller chunks in methods:

<~method myMethod>
    <p>In myMethod</p>
</~method>

To include the content in the method, call it as you would with any method in JavaScript - methods are turned into ordinary JavaScript functions attached to the template's prototype:

<% this.myMethod() %>

Methods can also specify an parameter list and accept arguments:

<~method greet (name) >
    <p>Hello <%= name %>.</p>
</~method>

Arguments are passed as you would expect:

<% this.myMethod('World') %>

As methods are turned into ordinary JavaScript functions, each method defines its own scope. However, methods are not evaluated in the scope of the surrounding content, so local variables and functions defined outside of the method will not be visible within it. See Begin Blocks for a mechanism for defining local variables that are visible to all methods within a template, as well as the main template content itself (which is just a special type of method internally).

Inherit Directive - Controlling Inheritance

Spectrum uses template inheritance to allow you to wrap the content of your template with another template (see Template Inheritance). Use the inherit directive to prevent inheritance or to specify the template to inherit from explicitly. The inherit directive can be anywhere within the top-level of your template - i.e. not within a method or other block tag. To turn off inheritance for a template:

<~inherit none />

To inherit from template other than the default (see Tempate Inheritance), specify the path to the parent template from the template root:

<~inherit "/path/to/parent.spv" />

Init Block - Performing Per Invocation Setup

When a template is rendered, an instance of it is first created. Methods called during the rendering of the template are called on this instance. An init block allows you to include some JavaScript to initialise the instance after it has been created:

<~init>
    this.section = 'faqs';
</~init>

This feature is often used to add data to a template that is used to control the way part of the page is rendered by a parent template. For example, you might use this to indicate to a parent template, which navigation link should be highlighted for the current page.

Begin Block - Shared Data and Functionality

Begin blocks are similar to init blocks, only they are only executed once for each template rather than for each new instance. The invocant (i.e. value of this) is the prototype object (i.e. the value of the prototype property of the prototype/constructor function) for the template instances. The begin block is executed in the parent scope of the rest of the code in the template, so any variables or functions declared within it can be used anywhere in the template.

<~begin>
    this.section = 'faqs';
    function templateScopedFunction () {
        // ...
    }
    var templateScopedVariable = 'foo';
</~begin>

The effect of the property assignment in the above example is the same as that for the init block above - the proprety is available on the template instance. The difference is quite subtle, the proprety assigned to the prototype object in the begin block is shared between all instances of the template and can be overridden for an intervidual template instance.