You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|**Variables and Substitution (`${..}`)**| Insert dynamic values or evaluate expressions | Build labels, topics, IDs, or computed values |
29
31
|**Conditionals (`!if`)**| Conditionally include or exclude YAML blocks | Enable or disable features when using packages or template flags |
32
+
|**Loops (`!for`)**| Generate repeated YAML blocks from a list or map | Create multiple items, channels, or thing definitions from structured data |
30
33
|**Include (`!include`)**| Insert the contents of another file | Reuse YAML across files; parameterize reusable blocks |
31
34
|**Templates (`!insert`)**| Reuse YAML defined within the same file | Local parameterized blocks; reusable channel or item fragments |
32
35
|**Packages**| Bundle multiple top-level sections into one reusable unit | Define reusable device structures containing things, items, metadata; sourced from external files or templates |
@@ -37,6 +40,7 @@ Each feature has a dedicated documentation page:
All notable changes to the `YamlComposer` component will be documented in this file.
4
+
5
+
## [openHAB 5.3]
6
+
7
+
### New Features
8
+
9
+
-**[Key-Level `!if`](conditionals#keylevel-form):** Added a shorthand form for the `!if` tag to streamline conditional blocks.
10
+
-**[Loop Support](loops):** Added `!for` directive for dynamic sequence iteration and templating.
11
+
-**Jinjava Functions & Enumerate:** Added [range()](variables#range), and `enumerate` (as both a filter and function supporting lists and maps with `.key`/`.value` entry accessors) to be used in expressions and loops.
12
+
-**[Ruby-Style Ranges](variables#ruby-style-range-syntax):** Added support for Ruby-style range syntax (`[1..5]` inclusive and `[1...5]` exclusive) as an alternative syntax for `range()`.
The `!if` tag performs logical branching during the **preprocessing phase**.
3
+
Conditional tags perform logical branching during the **preprocessing phase**.
4
4
5
5
> **Note:** Conditions are evaluated **once** when the YAML file is loaded.
6
6
> These are not runtime rules.
7
7
> They do not react to live state changes in openHAB.
8
8
9
9
[[toc]]
10
10
11
-
## When to Use `!if`
11
+
## When to Use Conditional Tags
12
12
13
-
Use the `!if` tag to adapt your configuration based on the **Resolution Context** (variables defined in the file, injected via `!include` or `!insert`, or [environment globals](variables.md#env-to-access-environment-variables)).
13
+
Use conditional tags to adapt your configuration based on the **Resolution Context**.
14
+
The Resolution Context includes variables defined in the file, variables injected via `!include` or `!insert`, and [environment globals](variables.md#env-to-access-environment-variables).
15
+
16
+
Conditional tags are useful for selecting configuration blocks, enabling optional features, or merging additional properties.
14
17
15
18
-**Conditional Snippets**: choose between alternative configuration blocks or values.
16
19
-**Optional Properties**: conditionally merge in additional settings using [merge keys (<<)](merge-keys.md).
20
+
-**Multi-Branch Logic**: select one of several possible configuration branches.
21
+
22
+
## Conditional Forms
23
+
24
+
The conditional system supports three forms:
25
+
26
+
-**Key‑Level Form**: uses `!if`, `!elseif` (and aliases `!elsif`, `!elif`), and `!else` as map keys.
27
+
-**Mapping Form**: uses `if:`, `then:`, and `else:` keys inside a single mapping.
28
+
-**Sequence Form**: uses `if:`, `elseif:`, and `else:` entries inside a list.
29
+
30
+
All forms evaluate expressions once during preprocessing.
31
+
32
+
### Differences Between the Three Forms
17
33
18
-
## Basic Syntax
34
+
Each form serves a different purpose and behaves differently when used inside maps or lists.
35
+
The table below summarizes the key differences so you can choose the right form before diving into the detailed syntax.
19
36
20
-
The `!if` tag supports two forms: a **Mapping Form** for simple logic and a **Sequence Form** for multiple branches.
|**Behavior in Maps**| Merges nested key‑value pairs directly into the parent map | Resolves to a single value | Resolves to a single value |
41
+
|**Behavior in Lists**| Splices items directly into the parent list | Returns a single list element (branch may itself be a list) | Returns a single list element (branch may itself be a list) |
|**Unmatched Fallback**| Inactive branches are omitted entirely | Resolves to `null`| Resolves to `null`|
44
+
|**Primary Use Case**| Conditionally merging groups of properties or inserting multiple inline list items | Simple ternary scalar/container assignment | Multi‑branch ternary scalar/container assignment |
21
45
22
-
The `if:` and `elseif:` keys are treated as **implicit expressions**.
23
-
You do not need to wrap the expression in `${...}`.
46
+
## Key‑Level Form
24
47
25
-
### Mapping Form (Simple)
48
+
The key‑level form applies conditional tags directly as map keys.
49
+
The tags `!if`, `!elseif` (and its aliases `!elsif`, `!elif`), and `!else` allow multi‑branch logic using separate map entries.
50
+
Each tag evaluates its expression (except `!else`, which has no expression).
51
+
The nested map underneath the selected tag is merged into the parent map.
52
+
53
+
Use this form when you want to conditionally merge map content into a parent structure.
54
+
55
+
::: tip Hints
56
+
57
+
- Expressions may be quoted or unquoted.
58
+
Quote expressions when they contain characters YAML might misinterpret, such as `:` or `#`.
59
+
- If the expression is truthy, the nested map is merged.
60
+
- If the expression is falsy, the nested map is ignored.
61
+
- Branches are evaluated in order from top to bottom.
62
+
Only the first truthy branch is selected.
63
+
Inactive branches are ignored.
64
+
65
+
:::
26
66
27
-
Use this for simple if/else decisions.
67
+
### Simple Example
68
+
69
+
```yaml
70
+
variables:
71
+
items_count: 20
72
+
things_count: 5
73
+
74
+
test:
75
+
!if '"bar" == "bar"':
76
+
foo: bar
77
+
!if items_count > 10:
78
+
items: a lot of items
79
+
!if things_count > 10:
80
+
things: a lot of things
81
+
other: baz
82
+
```
83
+
84
+
Result:
85
+
86
+
```yaml
87
+
test:
88
+
foo: bar
89
+
items: a lot of items
90
+
other: baz
91
+
```
92
+
93
+
### Multi‑Branch Example
94
+
95
+
```yaml
96
+
mode:
97
+
!if "env == 'prod'":
98
+
value: "production"
99
+
!elseif "env == 'staging'":
100
+
value: "staging"
101
+
!elif "env == 'dev'": # !elseif, !elif, and !elsif can be used interchangeably
102
+
value: "development"
103
+
!else:
104
+
value: "unknown"
105
+
```
106
+
107
+
Result:
108
+
109
+
```yaml
110
+
mode:
111
+
value: "production"
112
+
```
113
+
114
+
### Key Uniqueness
115
+
116
+
Each conditional tag is a map key.
117
+
YAML requires each key to be unique.
118
+
A duplicate‑key error occurs only when two conditional tags have identical key scalars.
119
+
Inline comments may be used to make identical expressions unique.
120
+
121
+
```yaml
122
+
test:
123
+
!if "true # unique 1":
124
+
foo: bar
125
+
!if "true # unique 2":
126
+
qux: quux
127
+
!if "true # unique 3":
128
+
corge: grault
129
+
```
130
+
131
+
### Returning Simple Values
132
+
133
+
The _key‑level form_ is intended for returning maps and lists.
134
+
Use inline expressions when you want to return a simple scalar value.
135
+
Inline expressions do not require conditional tags.
136
+
Inline expressions evaluate directly to a single value.
137
+
138
+
```yaml
139
+
foo: ${"High" if 5 > 2 else "Low"}
140
+
```
141
+
142
+
Alternatively the other two forms below also return a single value.
143
+
144
+
## Mapping Form
145
+
146
+
Use the mapping form for simple if/else decisions inside a single block.
0 commit comments