The template language
Lexical structure
Names, strings, numbers, comments, keywords and the line rule.
A template is UTF-8 text. It's read as a sequence of tokens: names, strings, numbers, operators and punctuation, separated by whitespace and comments. This chapter defines each kind of token, and the few places where spacing or line breaks matter.
Whitespace and comments
Spaces, tabs and line breaks separate tokens and are otherwise ignored, except where noted under The line rule.
A comment starts with // and runs to the end of the line. There are no block comments.
// A comment on its own line.
p "Hello" // and one after a nodeNames
A name starts with an ASCII letter or _, and continues with ASCII letters, digits and _.
A - or a . also continues a name when a letter, digit or _ follows it:
| Text | Tokens |
|---|---|
aria-live | one name |
post.title | one name: a path, the field title of post |
a - b | a, -, b |
a-b | one name, a-b |
t->t.done | t, ->, t.done |
So subtraction needs spaces around the - when its left side is a name.
A name with dots is a path: post.author.name reads post, then its field author, then that one's field name. After ), ] or }, a . is the field operator: first(posts).title, { a: 1 }.a.
Numbers
A number is decimal digits with an optional fraction: 0, 42, 3.25. There are no exponents, no hexadecimal and no separators. All numbers are 64-bit floating point.
A - directly before a digit is part of the number (-1) unless the token before it ends an operand, in which case it subtracts:
| Text | Means |
|---|---|
x(n: -1) | the attribute n is minus one |
a -1 | a minus one |
count - 1 | count minus one |
[1, -2] | a list of one and minus two |
Strings
A string is text between double quotes, on any number of lines.
| Escape | Means |
|---|---|
" | a double quote |
\ | a backslash |
n | a line break |
t | a tab |
{{ and }} | literal braces |
Interpolation. {expression} inside a string is replaced by the expression's value as text. Inside the braces, a quote is written \":
p "Hello {user.name ?? \"stranger\"}, you have {count} messages."How each kind of value becomes text is described under Expressions.
Operators and punctuation
| Token | Used for |
|---|---|
( ) | attribute lists, calls, grouping, lambda parameters |
{ } | children, records, interpolation |
[ ] | lists |
: | attribute and record values |
, | separating attributes, arguments, items and steps |
@ | events: @click |
= | declarations |
<- | setting state in a step |
+ - * / % | arithmetic, and + joins text and lists |
== != < <= > >= | comparison |
&& || ! | logic |
?? | a fallback for null |
|> | piping a value into a call |
-> | lambdas |
| | record update: { r | a: 1 } |
. | a field, after ), ] or } |
<- needs a space or line break after it. a <- 1 sets a, but a <-1 is a < -1, a comparison.
Keywords
These names are reserved everywhere, and can't be used as names:
| Keyword | Meaning |
|---|---|
if else then | conditionals, in nodes and in expressions |
for in | loops |
true false | booleans |
null | no value |
These are keywords only in one place, and are ordinary names everywhere else:
| Word | A keyword when |
|---|---|
state let on load | at the top level, followed by a name (and =, or ( for on) |
every after | at the top level, followed by a number, frame, or a name and then when or = |
when | in a timer, after its time |
frame | after every |
So an element can be called on, and a prop can be called state:
on "This element is called on."
p(state: "fine") "So is this prop."The line rule
Layout is free, with one exception: a string on the same line as an element is that element's text, and a string on a later line is a separate node.
p "This is the paragraph's text."
"This is a text node after the paragraph."A declaration's steps can continue on the next line after a comma or an operator; see Declarations.
Templates in Rust
Inside template! in Rust, the template is written as Rust tokens and rebuilt from their positions, so the same rules apply. Rust's string literals work as usual, raw strings included, and {{ and }} are literal braces as in any template.