> For the complete documentation index, see [llms.txt](https://plugins.elitefantasy.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://plugins.elitefantasy.net/mechanics/unearthmechanic/template-system.md).

# Template System

## Introduction <a href="#introduction" id="introduction"></a>

The template system allows you to reuse configurations across blocks, furniture, stages and other sections of UnearthMechanic.

Templates are expanded before UnearthMechanic processes the configuration. Therefore, once they have been resolved, the system continues to use the same configuration format and behaviour as usual.

Creating a template

Templates can be declared at the root of any YAML file:

```yaml
templates:
  unearth:brushable:
    base: "${base}"
    tool:
      - mc:brush
    transformation:
      stages:
        1:
          block_id: "${first_stage}"
        2:
          block_id: "${final_stage}"
```

It is also valid to declare them within `undeath.templates`:

```yaml
unearth:
  templates:
    unearth:brushable:
      base: "${base}"
      tool:
        - mc:brush
```

The template identifier must be unique. We recommend using the following format:

```
namespace:template_id
```

Templates can be used from within other YAML files.

Using a template

To apply a template, use the \`template\` property:

```yaml
unearth:
  block:
    archaeology:suspicious_sand:
      template: unearth:brushable
      arguments:
        base: ce:archaeology:suspicious_sand
        first_stage: ce:archaeology:suspicious_sand_1
        final_stage: mc:sand
```

The above configuration is processed as if it had been written as follows:

```yaml
unearth:
  block:
    archaeology:suspicious_sand:
      base: ce:archaeology:suspicious_sand
      tool:
        - mc:brush
      transformation:
        stages:
          1:
            block_id: ce:archaeology:suspicious_sand_1

          2:
            block_id: mc:sand
```

## Arguments

Arguments replace placeholders in the format `${argument}`

```yaml
templates:
  unearth:drop_stage:
    block_id: "${target}"
    drops:
      - "${drop};1;${chance}"
```

```yaml
unearth:
  block:
    archaeology:sand:
      template: unearth:drop_stage
      arguments:
        target: mc:sand
        drop: ce:archaeology:artifact
        chance: 25
```

Arguments are processed in the order in which they are written. An argument may use one that has been declared previously

```yaml
arguments:
  material: mud
  variant: bricks
  result: "${material}_${variant}"
```

When a placeholder occupies the entire value, it retains its original type:

```yaml
arguments:
  protected: true
  delay: 20
  tools:
    - mc:brush
    - mc:shovel
```

```yaml
no_protect: "${protected}"
delay: "${delay}"
tool: "${tools}"
```

### Default values

You can specify a default value using `-`

```yaml
delay: "${delay:-0}"
remove: "${remove:-false}"
permission: "${permission:-unearth.use}"
```

The default value is used when the argument has not been provided.

The following simple default values are currently supported:

* Text.
* Numbers.
* Booleans.
* null.
* Numbers with the suffixes d and f.

### Namespace and ID

Each configuration automatically receives two special arguments:

`${__NAMESPACE__}`

`${__ID__}`

Example:

```yaml
unearth:
  block:
    archaeology:suspicious_sand:
      template: unearth:named
```

```yaml
templates:
  unearth:named:
    permission: "unearth.${__NAMESPACE__}.${__ID__}"
```

Result:

```yaml
permission: unearth.archaeology.suspicious_sand
```

If the identifier does not contain a namespace, `unearth` is used as the default namespace.

### Text modifiers

#### Capitalising words

```yml
arguments:
  material: suspicious_sand
```

```yml
${material^}
```

Result:

```yml
Suspicious Sand
```

#### Convert to uppercase

```yml
${material^^}
```

Result:

```yml
SUSPICIOUS_SAND
```

### Multiple templates

A configuration can use several templates:

```yaml
unearth:
  block:
    archaeology:suspicious_sand:
      template:
        - unearth:brushable
        - unearth:with_drops
        - unearth:with_sounds
```

Templates are applied from top to bottom:

* Maps are combined recursively.
* Lists are concatenated.
* The individual values from the last template replace the previous ones.

Example:

```yaml
templates:
  unearth:first:
    tool:
      - mc:brush
    delay: 10

  unearth:second:
    tool:
      - mc:shovel
    delay: 20
```

The result will be:

```yaml
tool:
  - mc:brush
  - mc:shovel

delay: 20
```

### Merges

merges allows you to add values to the generated configuration:

```yaml
unearth:
  block:
    archaeology:suspicious_sand:
      template: unearth:brushable
      arguments:
        base: ce:archaeology:suspicious_sand
        first_stage: ce:archaeology:suspicious_sand_1
        final_stage: mc:sand
      merges:
        transformation:
          stages:
            1:
              sounds:
                - sound: minecraft:block.sand.break
                  volume: 1.0
                  pitch: 1.0
```

Maps are combined recursively and lists are appended to existing ones.

### Overrides

'overrides' completely replaces the specified value:

```yaml
unearth:
  block:
    archaeology:suspicious_sand:
      template: unearth:brushable
      overrides:
        tool:
          - ce:archaeology:soft_brush
```

Even if the template already contains tools, the list will be completely replaced:

```yaml
tool:
  - ce:archaeology:soft_brush
```

### Order of application

The configuration is built in the following order:

1. Templates, in the order specified.
2. Properties entered directly in the configuration.
3. merges.
4. overrides.

This means that overrides always take precedence.

### Nested templates

A template can use another template:

```yaml
templates:
  unearth:base_stage:
    block_id: "${target}"
    delay: "${delay:-0}"

  unearth:brushable:
    base: "${base}"

    transformation:
      stages:
        1:
          template: unearth:base_stage

          arguments:
            target: "${first_stage}"
            delay: 10
```

Templates can also be used directly within stages, sequences or other nested sections.

UnearthMechanic detects circular references:

```yaml
templates:
  unearth:first:
    template: unearth:second

  unearth:second:
    template: unearth:first
```

This configuration will be rejected and a warning will be displayed in the console.

### Conditional arguments

The `condition` type selects a value based on a condition:

```yaml
arguments:
  remove_stage:
    type: condition
    condition: "${should_remove:-false}"
    on_true: true
    on_false: false
```

#### Selection using `when`

when allows you to transform a value using different cases:

```yaml
arguments:
  tool:
    type: when
    source: "${material}"
    when:
      sand: mc:brush
      stone: mc:pickaxe
      dirt: mc:shovel
    fallback: mc:air
```

Uppercase and lowercase conversion

```yaml
arguments:
  uppercase_material:
    type: to_upper_case
    value: "${material}"
    locale: en
```

```yaml
arguments:
  lowercase_material:
    type: to_lower_case
    value: "${material}"
    locale: en
```

### Maps containing 'type'

A map used as an argument may contain a property called `type`. To prevent UnearthMechanic from interpreting this as a special type of argument, use:

```yaml
arguments:
  custom_data:
    __skip_template_argument__: {}
    type: custom
    value: example
```

The marker will not appear in the resulting settings.

### Escaping placeholders

To write ${argument} as literal text, add a backslash:

```yaml
message: "\${argument}"
```

Result:

```yaml
${argument}
```

Individual keys may also go missing:

```yaml
\{
\}
```

## Configuration errors

UnearthMechanic will display a warning and skip the affected settings when it encounters:

* A non-existent template.
* A circular reference.
* A template whose content is not a YAML section.
* An unsupported special argument.
* An invalid value for merges, overrides or arguments.

If two files declare the same template identifier, the most recently loaded definition will override the previous one. You should not rely on this behaviour; always use unique identifiers.
