Template Markup Language (TML) Reference

Table of contents


Introduction

The easiest way to create a Template object is using TML (Template Markup Language). TML is JavaScript template string that uses tml as the template function. The basic form of TML is the same as XML with several additional features.

Tags

The a TML element tag can be a standard HTML tag string or strings associated with Components published with view.defineComponentTag(). By convention, the tag string for published Components begins with a capital letter. For example:

tml`<Page title="A Page">...</Page>`

Tag strings that don’t begin with a capital letter and don't match any published Components are assumed to be standard HTML tags. These are passed to the built-in Html Component that uses the tag to create a standard HTML DOM element with the same attributes and children. TML can also use a direct reference to the Component class object. For example:

tml`<${MyComponentClass} ...>...</>`

State variable references

TML has a shorthand to reference state variables using {{...}} notation. For example: {{myStaveVarId}}. This will insert an input or output element that reflects the value of the state variable. There are other forms of state variable reference modify how the state variable is displayed. See Displaying State Variables.

The following forms are recognized:

Custom character entities

TML character entities take the same form as standard HMTL character entities. For example, &myEntity; will insert the custom Template or string associated with myEntity. Numeric entities such as &#169; are also recognized. An & that is not followed by word characters and a terminating ; (for example a & b or &foo bar) is treated as plain text.

The built-in entities are defined in the charEntity.js file. When TML encounters an entity string, it inserts an CharEntity Component that will extract the entity’s value (a string, a Template object, or an array of string and/or Template objects) and insert it as its contents. Many, but not all, standard HTML entities are supported. Here are some of the non-standard built-in entities:

The complete list is in the Character Entity Reference.

Attributes from object properties

In TML, you can fill in entity attributes from an object’s enumerable properties using ...${object}. For example, if an object were defined as follows:

const props = {className: "foo bar", id: "myElement"};

then the following TML string:

tml`<div ...${props}>...</>`

will be equivalent to:

tml`<div className="foo bar" id="myElement">...</>`

when the template string is evaluated. If the object has different properties or values the next time the template string is evaluated, the attribute will change accordingly.

Simple attribute values without quotes

An attribute that takes a string without spaces can delete the quotes around the string. For example:

tml`<div id=myElement>...</>`

Interpolation in quoted attribute values

Interpolated values may be embedded in a quoted attribute value. The pieces are concatenated into a string. For example:

tml`<div class="a ${x} b">...</>`

Simple true attributes

Specifying an attribute without an ‘=’ is equivalent to setting it to true in the Template properties. For example:

tml`<input autofocus />`

Is equivalent to:

tml`<input autofocus=${true} />`

Self-closing and closing tags

An element can be self-closing: <br/> or <input autofocus />.

Closing tags are never matched by name. Any closing tag, such as </>, </div>, or </ When >, simply closes the current element. Mismatched names are not detected, so the shorthand </> is normal practice.

Comments

<!-- comments --> are supported. They are dropped and do not appear in the result.

Non-template children

TML entities are not restricted to having strings or entities as children. Most components will also accept an array. For example:

tml`
	<div>
		${[
			"foo",
			tml`<div>another div</>`
		]}
	</div>
`

Some Components require other types of children. For example, the <When> Component requires a function. For example:

tml`
	<When hasChanged=myStateVar>
		${io => (io.myStateVar.value > 10 ? "warning" : "")}
	</ When >
`

Fragments

An <> entity in the TML string will create a Fragment Component. It is useful in cases where a Component requires a single child. The Fragment Component simply wraps its children. In general, this is not required in MVCS.

Whitespace trimming

When used as a tagged template, a leading blank line (newline plus surrounding whitespace) at the start of the first static string and a trailing one at the end of the last static string are trimmed, so an indented multi-line template does not produce stray whitespace children. Whitespace-only string children are also dropped by the Template constructor. Runtime strings (see below) are not trimmed.

Return value

A TML expression returns a single node when there is one top-level node, or an array of nodes when there are several. A node is a Template object, a string, or a number.

Runtime strings

tml can also be called as a plain function with a single string argument, tml(string), to parse a string built at run time. Such strings are not trimmed (so entities at the edges are preserved) and are not cached. An empty string or a non-string argument is returned unchanged.

Helper functions

Global

tml is also available as the global window.tml.