Syntax and attributes
The document
A template is one root element with any number of children. The root is usually a Panel or another container.
xml
<Panel layout="vbox" spacing="8">
<!-- Comments are ignored. -->
<Label text="Name" />
<TextInput placeholder="Your name" width="240" />
</Panel>The parser is small and forgiving:
| Rule | Detail |
|---|---|
| Tag names | Case-sensitive, and must be a known tag or one you registered. Anything else is a compile error. |
| Attribute quotes | Double or single quotes. An unquoted value runs to the next space or >. |
| Valueless attributes | <Window modal> means modal="true". |
| Entities | &, <, >, ", ' and numeric references (★, ★). Unknown entities stay as written. |
| Skipped | Comments, processing instructions (<?xml ...?>) and <!DOCTYPE>-style directives. |
| CDATA | <![CDATA[ ... ]]> is plain text. |
| Closing tags | An end tag closes the innermost open element whatever its name. Write matching tags anyway: the next reader will thank you. |
| Prefixes | bind:, on: and ui: on attributes have meaning. A prefix on an element name is dropped. |
Escape < and & inside attribute values (<, &). That matters in expressions: write count < 10, or flip it to 10 > count.
Text content
Text between the tags of an element becomes its text, and it may contain {{expression}} interpolations:
xml
<Label>Hello, {{name}}! You have {{count}} new messages.</Label>This is the same as bind:text="'Hello, ' + name + '! You have ' + count + ' new messages.'". A piece that fails to parse stays as literal text. Text without {{ is a plain value.
RichText is the exception: markup children such as <b> and <color> are kept as markup. The tags are listed on Display widgets.
Attribute kinds
| Form | Example | When it is applied |
|---|---|---|
| Static | text="Save" | Once, when the widget is built. |
| Bound | bind:text="title" | Now, and again whenever a ref the expression reads changes. |
| Event | on:click="save", on:click="select(item)" | Calls callMethod("save") when the widget fires it. With arguments, calls callMethod("select", [item]). |
| Directive | ui:show="ready" | Structural: visibility or repetition. |
Each tag has a fixed set of attributes it understands. An attribute it does not know is ignored without an error, so a typo shows up as "nothing happened". The tag reference lists them all.
Value formats
| Kind | Format | Examples |
|---|---|---|
| Number | Decimal | width="240", spacing="8.5" |
| Boolean | true or 1 is true, anything else is false | modal="true" |
| Color | #RRGGBB or #RRGGBBAA. Any other form is transparent black. | color="#7ab3ff", background="#00000080" |
| Size | width,height | size="200,32" |
| Insets | all, vertical,horizontal, or top,right,bottom,left | padding="12", padding="8,16", padding="4,8,4,8" |
| Border | color,width | border="#2e3340,1" |
| Range | min,max | range="0,100" |
| List | Comma-separated, blanks dropped | options="Easy,Normal,Hard" |
| Alignment | start, center, end, space-between | align="center" |
| Anchor | top-left, top-center, top-right, middle-left, center, middle-right, bottom-left, bottom-center, bottom-right | anchor="bottom-right" |
| Variant | primary, secondary, accent, neutral, danger, success, warning, info, custom1 to custom40, or a name your theme defines | variant="danger" |
Common attributes
Every tag accepts these.
| Attribute | Meaning |
|---|---|
name (or id) | The component's name. screen.findByName("save") finds it after instantiate. name wins if both are given. |
x, y | An offset added on top of the position the layout gives. In a parent with no layout, this is the position. |
width, height | Size in pixels. Many tags also take size="w,h". |
minWidth, minHeight, maxWidth, maxHeight | Size limits for layout. |
enabled | false disables the widget. |
visible | false hides it. |
layout | vbox, hbox, grid, flow, anchor, or anything else for none. |
spacing | Gap between children. |
gridColumns | Columns for layout="grid". |
flow-row-gap | Gap between wrapped rows for layout="flow". |
padding, margin | Insets (see value formats). |
align, justify | Cross-axis and main-axis alignment of children. |
fill | width, height or both: stretch to the parent. |
grow | Flex weight inside a vbox or hbox. |
zIndex | Drawing order among siblings. |
variant | The theme variant. |
In an anchor layout, children also take anchor, offsetX and offsetY (or anchorOffsetX and anchorOffsetY).
Errors
registerXML throws a TemplateError whose message starts with line:col:, for example:
text
template "settings": 4:9: unknown component type "Buton"Other compile errors: a bad expression (bind:text expression error: ...), an unknown directive (unknown directive ui:hide), a malformed ui:for, and a <Theme> element that is empty or not valid JSON.
instantiate throws when a template name is not registered (template "x" not found). If a widget fails to build, the half-built tree is disposed before the error reaches you.