Templates
Anathema has a template language to describe user interfaces. This makes it possible to ship the template(s) together with the compiled binary so the application can be customised without having to be recompiled.
The element syntax looks as follows: <element> <attributes> <value>
Element name
| Start of (optional) attributes
| | Attribute name
| | | Attribute value
| | | | Attribute separator End of attributes
| | | | | | Values / Text
| | | | | | |
| | | | | | |------+-+-+
| | | | | | | | | |
element [optional: "attribute", separated: "by a comma"] "text" 1 2 ident
Elements don't receive events (only Component
s do) and should be thought of as
something that is only drawn to screen.
There is for instance no "input" element. To represent an input the component would handle the key press events and simply pass the collected values as a string via state.
Comments
Use //
to add comments to a template:
text "I will render"
// text "I will not"
Attributes
Element attributes are optional.
Attributes consists of a collection of ident
, :
, and value
.
An ident
has to start with a letter (a-zA-Z
) and can contain one or more _
.
Example:
element [attribute_a: "some string", attribute_b: false]
An attribute name is always an ident, however the value can be anything that
implements State
.
Default value types:
A literal value can be one of the following:
- string:
"Empty vessel, under the sun"
- integer:
123
- float:
1.23
- hex:
#fab
or#ffaabb
- boolean:
true
orfalse
- list:
[1, 2, 3]
- map:
{"key": "value"}
To access a state value use an ident
(a string without spaces that is not
wrapped in quotes).
text "string literal"
text ident
Elements and children
Some elements can have one or more children.
Example: a border element with a text element inside
border
text "look, a border"
Loops
It's possible to loop over the elements of a collection.
The syntax for loops are for <element> in <collection>
.
Example: looping over static values
for value in [1, 2, "hello", 3]
text value
Elements generated by the loop can be thought of as belonging to the parent element as the loop it self is not a element. See example below.
Example: mixing loops and elements
vstack
text "start"
for val in [1, 2, 3]
text "some value: " val "."
text "end"
The above example would render:
start
some value: 1.
some value: 2.
some value: 3.
end
For-loops also expose a loop
variable that is set to the current loop iteration.
Example: loop
variable
vstack
for val in ["a", "b", "c", "d"]
text "#" loop ": " val
The above example would render:
#0: a
#1: b
#2: c
#3: d
Note: For-loops do not work inside attributes, and can only produce elements.
If / Else
It's possible to use if
and else
to determine what to layout.
Example:
if true
text "It's true!"
if value > 10
text "Larger than ten"
else if value > 5
text "Larger than five but less than ten"
else
text "It's a small value..."
Operators
- Equality
==
- Greater than
>
- Greater than or equals
>=
- Less than
<
- Less than or equals
<=
- And
&&
- Or
||
Note: just like for-loops it's not possible to use if / else with attributes.
To determine the value of an attribute depending on some condition this should be handled by the state.