• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HML
2
3
4The OpenHarmony Markup Language (HML) is an HTML-like language that allows you to build pages based on components and events. HML pages provide advanced capabilities such as data binding, event binding, loop rendering, conditional rendering, and logic control.
5
6
7## Page Structure
8
9
10```html
11<!-- xxx.hml -->
12<div class="item-container">
13  <text class="item-title">Image Show</text>
14  <div class="item-content">
15    <image src="/common/xxx.png" class="image"></image>
16  </div>
17</div>
18```
19
20
21## Data Binding
22
23
24```html
25<!-- xxx.hml -->
26<div class="item-container">
27  <text>{{content}}</text>            <!-- Display Hello World!-->
28  <text>{{key1}} {{key2}}</text>       <!-- Display Hello World-->
29  <text>key1 {{key1}}</text>           <!-- Display key1 Hello-->
30  <text>{{flag1 && flag2}}</text>      <!-- Display false-->
31  <text>{{flag1 || flag2}}</text>      <!-- Display true-->
32  <text>{{!flag1}}</text>              <!-- Display false-->
33</div>
34```
35
36Declare the variables used in the XML file for service widgets in the **data** field in the JSON file.
37
38```json
39{
40  "data": {
41    "content": "Hello World!",
42    "key1": "Hello",
43    "key2": "World",
44    "flag1": true,
45    "flag2": false
46  }
47}
48```
49
50>  **NOTE**
51>  - When using data binding, you can use the object operator or array operator on a key to access the bound data, for example, **{{key.value}}** and **{{key[0]}}**.
52>
53>  - String concatenation, logical operations, and ternary expressions are supported.
54>   - String concatenation:
55>      - A variable can be followed by another variable, for example, **{{key1}}{{key2}}**.
56>      - A variable can also be followed by a constant, for example, **"my name is {{name}}, i am from {{city}}."    "key1 {{key1}}"**.
57>   - Logical operations:
58>      - AND: {{flag1 && flag2}} (The AND operation can only be performed on two Boolean variables.)
59>      - OR: {{flag1 || flag2}} (The OR operation can only be performed on two Boolean variables.)
60>      - NOT: {{! flag1}} (The NOT operation can only be performed on a Boolean variable.)
61>   - Ternary expressions:
62>      - {{flag? key1: key2}} (**flag** is a Boolean variable. **key1** and **key2** can be variables or constants.)
63>   - Notes
64>      - The default value is **false** when a Boolean-specific operation is performed on a non-Boolean variable.
65>      - The preceding variable and operation parsing do not support nesting.
66
67## Event Binding
68
69Declare the events for service widgets in the **actions** field in the JSON file. Service widgets support the common click event only. The event must be declared explicitly. The event definition must contain the **action** field to describe the event type. Service widgets support redirection events (**router**) and message events (**message**). A redirection event is used for switching to the OpenHarmony application (the widget provider). A message event can transfer custom information to the service widget provider. Event parameters can be variables, which are defined using **{{}}**. If the **params** field is defined in the redirection event, you can pass **params** to the **onStart** method (as **intent**) of the started application to access the value.
70
71- Redirection event properties
72
73  Define the **abilityName** and **params** fields to implement direct redirection to the target application.
74
75  | Selector        | Example    | Default Value     | Description                                    |
76  | ----------- | ------ | -------- | ---------------------------------------- |
77  | action      | string | "router" | Event type.<br>- **"router"**: redirection event.<br>- **"message"**: message event.|
78  | abilityName | string | -        | Name of the ability to redirect to.                             |
79  | params      | Object | -        | Additional parameter passed during the redirection.                            |
80
81
82  ```json
83  {
84    "data": {
85      "mainAbility": "xxx.xxx.xxx"
86    },
87    "actions": {
88      "routerEvent": {
89        "action": "router",
90        "abilityName": "{{mainAbility}}",
91        "params":{}
92      }
93    }
94  }
95  ```
96
97You can also implement redirection to the target application using a **want**, which contains the **abilityName**, **bundleName**, and **parameters** fields.
98
99| Selector   | Type    | Default Value     | Description                                    |
100| ------ | ------ | -------- | ---------------------------------------- |
101| action | string | "router" | Event type.<br>- **"router"**: redirection event.<br>- **"message"**: message event.|
102| want   | [Want](../apis/js-apis-app-ability-want.md) | -        | Information about the target application. For details, see the **want** format.                    |
103
104
105```json
106  {
107      "data": {
108        "mainAbility": "xxx.xxx.xxx"
109      },
110      "actions": {
111        "routerEventName1": {
112          "action": "router",
113          "want": {
114            "bundleName": "com.example.myapplication",
115            "abilityName": "EntryAbility"
116          }
117        },
118        "routerEventName2": {
119          "action": "router",
120          "want": {
121            "action": "xxx.intent.action.DIAL",
122            "uri": "tel:12345678"
123          }
124        }
125      }
126    }
127```
128
129  In API version 8, the [featureAbility.getWant](../apis/js-apis-ability-featureAbility.md) API in the **onCreate** method of the **app.js** or **app.ets** file must be called for the **want** parameter to receive related parameters.
130
131- Message event properties
132
133  | Selector   | Example    | Default Value    | Description        |
134  | ------ | ------ | ------- | ------------ |
135  | action | string | message | Event type.     |
136  | params | Object | -       | Additional parameter passed during the redirection.|
137
138
139  ```json
140  {
141    "actions": {
142      "activeEvent": {
143        "action": "message",
144        "params": {}
145      }
146    }
147  }
148  ```
149
150- The following example shows two styles for binding the redirection event and message event:
151
152  ```html
153  <!-- xxx.hml -->
154  <div>
155    <!-- Regular format -->
156    <div onclick="activeEvent"></div>
157    <!-- Abbreviation -->
158    <div @click="activeEvent"></div>
159  </div>
160  ```
161
162
163## Loop Rendering
164
165
166```html
167<!-- xxx.hml -->
168<div class="array-container">
169  <!-- div loop rendering -->
170  <!-- By default, $item indicates the element in the array, and $idx indicates the index of the element in the array. -->
171  <div for="{{array}}" tid="id">
172    <text>{{$item.name}}</text>
173  </div>
174  <!-- Define the name for an element variable. -->
175  <div for="{{value in array}}" tid="id">
176    <text>{{value.name}}</text>
177  </div>
178  <!-- Define an element variable and its index name. -->
179  <div for="{{(index, value) in array}}" tid="id">
180    <text>{{value.name}}</text>
181  </div>
182</div>
183```
184
185
186```json
187{
188  "data": {
189    "array": [
190      {"id": 1, "name": "jack", "age": 18},
191      {"id": 2, "name": "tony", "age": 18}
192    ]
193  }
194}
195```
196
197The **tid** attribute accelerates the **for** loop and improves the re-rendering efficiency when data in a loop changes. The **tid** attribute specifies the unique ID of each element in the array. If it is not specified, the index of each element in the array is used as the ID. For example, **tid="id"** indicates that the **id** attribute of each element is its unique ID. The **for** loop supports the following statements:
198
199- for="array": **array** is an array object, whose element variable is **$item** by default.
200
201- for="v in array": **v** is a custom element variable, whose index is **$idx** by default.
202
203- for="(i, v) in array": **i** indicates the element index, and **v** indicates the element variable. All elements of the array object will be looped through.
204
205>  **NOTE**
206>  - Each element in the array must have the data attribute specified by **tid**. Otherwise, an exception may occur.
207>
208>  - The attribute specified by **tid** in the array must be unique. Otherwise, performance loss occurs. In the above example, only **id** and **name** can be used as **tid** because they are unique fields.
209>
210>  - The **tid** field does not support expressions.
211>
212>  - Nested **for** loops are not supported.
213>
214>  - When you use the **for** loop, ensure that the objects contained in the array are of the same type.
215
216
217## Conditional Rendering
218
219There are two ways to implement conditional rendering: **if-elif-else** or **show**.
220
221The **if-elif-else** statements must be used in sibling nodes. Otherwise, the compilation fails. The following example uses both ways to implement conditional rendering:
222
223
224```html
225<!-- xxx.hml -->
226<div>
227  <text if="{{show}}"> Hello-TV </text>
228  <text elif="{{display}}"> Hello-Wearable </text>
229  <text else> Hello-World </text>
230</div>
231```
232
233
234```json
235{
236  "data": {
237    "show": false,
238    "display": true
239  }
240}
241```
242
243If **show** is **true**, the node is rendered properly; if it is **false**, the display style will be **none**.
244
245
246```html
247<!-- xxx.hml -->
248<text show="{{visible}}"> Hello World </text>
249```
250
251
252```json
253{
254  "data": {
255    "visible": false
256  }
257}
258```
259
260
261## Logic Control Block
262
263**\<block>** makes loop rendering and conditional rendering more flexible. A **\<block>** will not be compiled as a real component. The **\<block>** supports the **if** attribute only.
264
265
266```html
267<!-- xxx.hml -->
268<div>
269  <block if="{{show}}">
270    <text>Hello</text>
271    <text>World</text>
272  </block>
273</div>
274```
275
276
277```json
278{
279  "data": {
280    "show": true
281  }
282}
283```
284