# Template Syntax
The structure and content of quick app components and pages are defined in templates, using an HTML-based markup language with essential components and events that enable user interaction.
This HTML-based template syntax allows you to declaratively bind the rendered DOM to the underlying component data. The system renders the pages using virtual DOM to offer reactivity, applying minimal DOM manipulations when the component states change.
The templating system enables the definition of static content and data interpolation.
A template section is identified by the <template>
tag in UX documents.
WARNING
Templates can only contain one root node (e.g., a <div>
element).
You can use <block>
as the root node.
You can include static content directly on the templates:
<template>
<text>Sample text</text>
</template>
# Decorators
You can customize filters to modify or decorate the content rendered in pages.
A filter is a method defined in the component instance. The method must have an argument (the input) and return a value after processing the data and applying the format.
For instance, a method to capitalize a text:
<script>
export default {
private: {
message: 'hello'
},
capitalize(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
</script>
To use a filter, you can add it to the end of the expression and separate it with a pipe (|
).
To apply the formatter of the previous example:
<template>
<text>{{ message | capitalize }}</text>
</template>
The filter uses the received the expression value as the first parameter.
These filters can be connected in a pipeline as in the following example.
<template>
<text>{{ message | filterA | filterB }}</text>
</template>
<script>
export default {
private: {
message: 'hello'
},
filterA(value) {
if (!value) return ''
return '(A) ' + value
},
filterB(value) {
if (!value) return ''
return '(B) ' + value
}
}
</script>
The result of the previous pipeline produces the text:
(B) (A) hello
# Data Binding
The most basic form of data binding is text interpolation using the syntax (double curly braces):
<template>
<text>{{message}}</text>
</template>
The mustache tag will be replaced with the value of the message
property from the current component instance. It will also be updated once the message
property changes.
The following example shows how to bind a data property with the template.
<template>
<text>{{message}}</text>
</template>
<script>
module.exports= {
data: {
message: 'Hello World!'
}
}
</script>
Data interpolation can be also used in element's attributes. Also with advanced operations inline:
<template>
<text style="{{'background-color:'+color}}">Static content</text>
</template>
<script>
module.exports= {
data: {
color: "red"
}
}
</script>
# List Rendering
We can use a data array to render a list of elements using the for
directive. This directive must be applied on an array in the instance of the component, and it generates two reserved local variables that can be used in the scope of the block where the for
directive is applied.
Children of the element that contains the for
directive may use the following variables:
$idx
: index of the array (from0
toarray.length - 1
)$item
: variable that contains the element in the array at the position$idx
.
The following example...
<template>
<div>
<div for="{{animals}}">
<text>Index: {{$idx}}</text>
<text>{{$item.identifier}}</text>
<text>{{$item.name}}</text>
</div>
</div>
</template>
<script>
module.exports={
data: {
animals: [
{
name: "cat",
identifier: "01"
},
{
name: "platypus",
identifier: "02"
},
{
name: "turtle",
identifier: "03"
}
]
}
}
</script>
rendering the following texts on the page:
Index: 0
01
cat
Index: 1
02
platypus
Index:2
03
turtle
The for
directive can use the tid
attribute to define the attribute of the array elements that must be used as a unique identifier of each array element. If tid
is not specified, the system considers the array index ($idx
) by default.
Use of tid
attribute in the loop directive, indicating that $item.identifier
is the unique identifier of the array elements:
<template>
<div>
<div for="{{animals}}" tid="identifier">
<text>Index: {{$idx}}</text>
<text>{{$item.identifier}}</text>
<text>{{$item.name}}</text>
</div>
</div>
</template>
We can use other alternative notations to define loops with the for
directive:
for="element in list"
, whereelement
is a the name of the variable that contains the array element that can be used in the loop. The default array index is$idx
.for="(index,element) in list"
, whereindex
is the array index, andelement
is the variable with the array item to be used in the loop.
WARNING
If The data attribute specified by tid
must exist and be unique.
# Conditional Rendering
The template could include directives to render blocks conditionally. If the condition defined by the directive is not met, the element is removed from the Virtual DOM.
There are two main types of directives to control the conditional rendering: if/elif/else
and show
.
# if/elif/else
Directives
The directive if
is used to conditionally render a block only when the directive's expression returns a truthy value.
<text if="{{condition1}}">If block</text>
It is also possible to add a complementary else
block:
<text if="{{condition1}}">If block</text>
<text else>Else section</text>
In case you need to chain "else if" blocks after the if
directive, you can use the elif
directive.
<template>
<div>
<text if="{{condition1}}">If block</text>
<text elif="{{condition2}}">ElIf part</text>
<text else>Else section</text>
</div>
</template>
<script>
module.exports= {
data: {
condition1: false,
condition2: true
}
}
</script>
The previous example renders:
ElIf part
WARNING
The if
, elif
, and else
blocks must be sibling nodes. Otherwise, the compilation fails.
# show
Directive
The effect of the conditional show
directive is equivalent to the display: none
CSS statement, so the elements within the block are in the Virtual DOM.
<template>
<text show="{{visible}}"> Hello World! </text>
</template>
<script>
module.exports= {
data: {
visible: false
}
}
</script>
TIP
Currently, the show
directive only applies to native components, and it does not cause any effect in custom components. For custom components, you can pass the conditional parameters through props
, and using show
directly in the inner elements.
TIP
You can use the basic <block>
element to control the conditional rendering. This element only supports the for
and if/elif/else
attributes. If no attribute is specified in a <block>
section, the section is treated as a transparent node in a build, and its sub-nodes are added to its parent <block>
node in the virtual DOM.
# Event Binding
We can listen to events on elements and run some scripts when they are triggered. We can use the name of the event with the prefix on
, or using the @
symbol.
For instance, the follow example binds the method press()
with the click
event of <div>
elements.
<template>
<div>
<!-- Normal format -->
<div onclick="press"></div>
<!-- Shortcut -->
<div @click="press"></div>
</div>
</template>
<script>
module.exports= {
press: function(e) {
this.title = 'You clicked!!'
}
}
</script>
The event handler includes an argument for the event that is triggered. In the case the method includes other parameters, the event is automatically added to the parameter list.
Read more in the Events section.
# Reusing Custom Components
Custom components can be reused from any component. You only need to import the custom component using the <import>
element in the UX file.
For instance:
<import name='cool-button' src='./cool-button'></import>
<template>
<div class="container">
<text class="title">Hi Quick Apps!</text>
<cool-button></cool-button>
</div>
</template>
Read more about components.