> ## Documentation Index
> Fetch the complete documentation index at: https://platform.docs.zenoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# YAML

> Hub client YAML configuration

## YAML

The YAML used in Target Builder is a [standard YAML](https://yaml.org) that has been extended with some specific YAML tags.

For initial acquaintance with the YAML read this article: [Learn X in Y minutes (Where X=yaml)](https://learnxinyminutes.com/docs/yaml/)

### Reserved fields

In the YAML files,  there are three "reserved" fields in the root:

* `components` ([`!ref`](#ref-compile-time-tag))
* `styles` ([styles](#styles))
* `~private`

***

#### `~private`

* It can be used to store data, which will be omited in build time, and will not be in target configuration. This field is processed by target-builder.

##### Example

```yaml theme={null}
~private:
  yourSecretKey: "secret value"
```

***

### List of supported tags

#### Compile-time tags

* [`!condition`](#condition-compile-time-tag)
* [`!include`](#include-compile-time-tag)
* [`!property`](#property-compile-time-tag)
* [`!ref`](#ref-compile-time-tag)

#### Run-time tags

* [`!component`](#component-run-time-tag)
* [`!cx`](#cx-run-time-tag)
* [`!expression`](#expression-run-time-tag)
* [`!function`](#function-run-time-tag)
* [`!repeat`](#repeat-run-time-tag)
* [`!t`](#t-run-time-tag)

#### Deprecated tags

* `!import`, use [`!include`](#include-compile-time-tag) instead
* `!variable`, use [`!property`](#property-compile-time-tag) instead
* `!boolean`
* `!number`

***

#### `!include` <sub>compile-time tag</sub>

* This tag is used to import/include any type of file into this place of YAML.
* This tag supports properties, which correspond to the parameters of this file.
* This tag internally opens any file as string, then processes by EJS ([https://ejs.co](https://ejs.co)), and then it passes the contents as a string (for other types) — or processes it by compiler if it is a supported file type (YAML, MD, HTML, LESS).
* You can use EJS for any kind of modifing file that depends on properties, such as—for example-generating some repeating parts of a document or setting values for some of the properties.
* The tag is always processed immediately when is used, except when it is used in the `components` field in root of YAML file (see [!ref](#ref-compile-time-tag)).
* The tag is used for including any type of file—not only for YAML but also for LESS, CSS, MD, HTML, etc.
* When you attempt to include a directory, the Target builder will look in this directory for the `index.yaml` or `index.yml` file. It will include this file if it is found. Keep in mind that you can include components like `!include ./components/button` instead of `!include ./components/button/index.yml`).

##### Syntax

*Short version (without properties)*:

```yaml theme={null}
!include ./path/file.ext
```

*Long version (with properties)*:

```yaml theme={null}
!include file: ./path/file.ext
property1: 'some'
property2: 123
```

##### Examples

```yaml theme={null}
list:
  - !include ./info.md
  - !include file: ./more_info.yml
    title: 'Hello'
    withoutHeader: true
```

```yaml theme={null}
something: !include ./something.yml
```

***

#### `!ref` <sub>compile-time tag</sub>

* This tag is used to reference some component into this place
* The source for the components is the `components` field in the root of YAML file.
* This tag can have properties that the same as the [!include](#include-compile-time-tag) tag
* The !ref tag properties have higher priority than [!include](#include-compile-time-tag) properties in `components` field
* You can make multiple references to a component, with different properties for each reference.

##### Syntax

```yaml theme={null}
!ref components: component_name
```

##### Examples

```yaml theme={null}
components:
  header: !include file: ./components/header.yml
    title: "Default title"
  bodyItem: !include ./components/body-item.yml
  footer: !include ./components/footer.yml

...

items:
  - !ref components: header
    title: 'Welcome'
  - !ref components: bodyItem
    name: 'First one'
  - !ref components: bodyItem
    name: 'Second one'
  - !ref components: footer
```

***

#### `!property` <sub>compile-time tag</sub>

* This tag is useful as a placeholder for the value of a propertys (in an [!include](#include-compile-time-tag) of a YAML file.
* While it is possible to use EJS for this, EJS only works with a string. It's not possible to pass some array or object using EJS, and this is the purpose of the !property tag.
  -This tag can have `default` value (only in the long version), which can contain any valid YAML value—including a string, number, array, or complex object.
* This tag can have `required: true` mark (only in long version), which will throw an error message while build target, when value is not filled (`default` value don't have any impact if `required: true` is set).
* If the property is not set, this tag is set to `undefined`, and field will not appear in the output JSON.

##### Syntax

*Short version (without default)*:

```yaml theme={null}
!property some_prop
```

*Long version (with default or required)*:

```yaml theme={null}
!property name: some_prop
default: 'Some default value'
required: true
```

##### Examples

```yaml theme={null}
items:
  - !property prop1
  - !property name: prop2
    default: 'Prop2 is not here :-)'
  - !property name: prop3
    required: true
```

***

#### `!condition` <sub>compile-time tag</sub>

* This tag is for removing or including some parts of YAML structure (in an [!include](#include-compile-time-tag) of a YAML file).
* The first parameter (key) can be either `include` or `omit`. `include` leaves the bject in the structure if the expression is a genuine value. `omit` removes the object from the structure if the expression is a genuine truly value.
* The second parameter (expression) is the expression in EJS format.
* This tag is valid only for object types and include/omit object in which is contained. (It is not permissible to apply this tag to a string or number value; use EJS isntead.)

##### Syntax

```yaml theme={null}
!condition include: typeof some_prop === "boolean" && some_prop === true
```

```yaml theme={null}
!condition omit: typeof some_prop === "string" && some_prop !== "foo"
```

##### Examples

```yaml theme={null}
items:
  - name: 'this item is not here :-('
    !condition include: typeof some_falsy_prop === "boolean" && some_falsy_prop === true
  - name: 'this item is here :-)'
    !condition omit: typeof some_falsy_prop === "boolean" && some_falsy_prop === true
```

***

#### `!component` <sub>run time tag</sub>

* This tag creates a component in **hub-client-core**. During execution, it is converted into a real React component in the HTML DOM.
* Every element is created by `React.createElement`, and property items will be used as children.
* The parameter is name of **hub-client-core** component, or any React Element such as div, span, h1, etc.

##### Syntax

```yaml theme={null}
!component as: some_component
property: 'foo'
```

##### Examples

```yaml theme={null}
items:
  - !component as: div
    items:
      - !component as: h1
        items: 'Hello'
      - !component as: HubClientMagicComponent
        doMagic: true
```

***

#### `!repeat` <sub>run time tag</sub>

* This tag creates a repeat snippet in the **hub-client-core**. At execution, this is evaluated in React.
* The parameter is any array (static or from *!expression*). For more information about the repeat snippet, see the **hub-client-core** documentation.

##### Syntax

```yaml theme={null}
!repeat some_item:
  - name: 'Some 1'
  - name: 'Some 2'
  - name: 'Some 3'
component:
  !component as: span
  items: !expression some_item.name
```

##### Examples

```yaml theme={null}
items:
  - !repeat car: !expression export.cars
    component:
      !component as: span
      items: !expression car.name
  - !repeat pair:
      - name: 'Some 1'
        value: 'Val 1'
      - name: 'Some 2'
        value: 'Val 2'
      - name: 'Some 3'
        value: 'Val 3'
    component:
      !component as: div
      items:
        - !component as: span
          items: !expression pair.name
        - !component as: span
          items: "!expression '(' + pair.value + ')'"
```

The **!repeat** expression provides a way to iterate on some collections and map components to it. You simply specify an array as the input collection (you can use an expression as well). Also specify a component that will be rendered `n` times (`n` is length of array).

Inside the component, you can access an item by expression that is stored in the key. In the expression, you can directly access an item of the array (`[key].item`) or its index (`[key].index`).

This is the format:

```yaml theme={null}
!repeat [key]: [array]
component: [some component]
```

**Examples**:

Here's an array from the api:

```yaml theme={null}
!repeat person: !expression flow.export.persons
component:
  !component as: span
  items: !expression person.item.name
```

Here's an array in yaml:

```yaml theme={null}
!repeat item:
  - Item 1
  - Item 2
component:
  !component as: span
  items: !expression item.item
```

***

#### `!expression` <sub>run time tag</sub>

* this tag creates an expression in **hub-client-core**. At execution, this is evaluated in React.
* The parameter is an expression. For more information about  expressions, see the **hub-client-core** documentation.

##### Syntax

*Short version (without parameters)*:

```yaml theme={null}
!expression 'some_expression'
```

*Long version (with parameters)*:

```yaml theme={null}
!expression eval: 'some_expression'
parameter_one: 'Some parameter value'
```

*Multiline*:

```yaml theme={null}
property:
  !expression: |
    const variable = 1;
    // More lines of JavaScript
    console.log('Hello', variable);
```

##### Examples

```yaml theme={null}
items:
  - !component as: span
    items:
      - !expression 'exports.someExportField'
  - !component as: span
    max:
      !expression eval: 'parseInt(param1) - param2'
      param1: !expression 'exports.someExportField'
      param2: !property test1
```

***

#### `!function` <sub>run time tag</sub>

* This tag creates a JS function in **hub-client-core**. At execution time, it evaluated in React and may be used as a paramater in the events of components.
* The parameter is a function body. For more info about expressions, see the **hub-client-core** documentation.

##### Syntax

*Short version (without parameters)*:

```yaml theme={null}
!function 'some_expression'
```

*Long version (with parameters)*:

```yaml theme={null}
!function eval: 'some_expression'
parameter_one: 'Some parameter value'
```

##### Examples

```yaml theme={null}
items:
  - !component as: div
    onClick: !function 'setSomething(arg1 + "A")'
  - !component as: div
    onClick:
      !function eval: 'doSomething(parseInt(param1) - param2)'
      param1: !expression 'exports.someExportField'
      param2: !property test1
  - !component as: div
    onClick: !function |
      var a = "A";
      var b = "B";
      return a + b + " = done";
```

***

#### `!t` <sub>run time tag</sub>

* This tag creates a translated string in **hub-client-core**. At execution time, it evaluated in React.
* The long version of this tag provides parameters. The first parameter is replaced with the second parameter.

##### Syntax

*Short version (without params)*:

```yaml theme={null}
!t Some text
```

*Long version (with params)*:

```yaml theme={null}
!t text: Some text with {paramOne} and {paramTwo}
paramOne: 'Zenoo'
paramTwo: !expression 'exports.someExportField'
```

##### Examples

```yaml theme={null}
items:
  - !component as: span
    items:
      - !expression 'exports.someExportField'
```

***

#### `!cx` <sub>run time tag</sub>

* This tag is shorcut for a `cx(...)` method call in **hub-client-core** expressions.
* The parameter must be array of classnames (after `args`).

##### Syntax

```yaml theme={null}
!cx args:
  - 'classOne'
  - 'classTwo'
  - !expression 'exports.someClassName'
```

##### Examples

```yaml theme={null}
items:
  - !component as: span
    className:
      !cx args:
        - 'classOne'
        - 'classTwo'
        - !expression 'exports.someClassName'
```
