# Placeholders

Learn how insert content from other attributes.

Placeholders let you reference and reuse values from other attributes in your content, helping you maintain consistency and avoid duplication.

For example, in a promotional banner, you can use placeholders to generate the value for the coupon code and the message:

![Placeholders](/assets/reference/content/definition/placeholders.png)

## Syntax

The basic syntax for a placeholder is `{{attribute}}`, where `attribute` is the path to the attribute you want to insert. You can optionally provide a fallback value by adding a pipe character `|`, like in `{{attribute | fallback value}}`.

The attribute paths can use two types of notation:

- **Name notation**\
  For referencing an attribute by its name, like `title`.
- **Index notation**\
  For referencing a list item by its index, like `features[0]`.

You can combine both notations to reference nested attributes. For example, `features[1].label`.

## Absolute paths

Absolute paths always start from the root of the content, regardless of where the placeholder is located.

Building on the initial example, if the promotion information were nested, you would reference the discount and coupon attributes like this:

![Absolute placeholders](/assets/reference/content/definition/absolute-placeholders.png)

> **Example: Content definition with absolute paths**
>
> Here is the content definition for the previous example:
>
> ```pmsjson
> {
>   "type": "structure",
>   "attributes": {
>     "message": {
>       "type": "text",
>       "value": {
>         "type": "static",
>         "value": "Get {{promotion.discount}}% off with code {{promotion.coupon}}!"
>       }
>     },
>     "promotion": {
>       "type": "structure",
>       "attributes": {
>         "discount": {
>           "type": "number",
>           "value": {
>             "type": "static",
>             "value": 30
>           }
>         },
>         "coupon": {
>           "type": "text",
>           "value": {
>             "type": "static",
>             "value": "SAVE{{promotion.discount}}"
>           }
>         }
>       }
>     }
>   }
> }
> ```

## Relative paths

Relative paths start with double dots `..` and use the location of the placeholder to resolve the path. For example, `{{..discount}}` references a sibling attribute, and `{{..[0]}}` references the first item in the parent list.

> **Question: What if I need to go up multiple levels?**
>
> You can reference attributes from higher levels by specifying the number of levels after the dots.
>
> For example, `{{..2.discount}}` refers to an attribute two levels up, where `..0` is the current level, `..1` is the parent, and so on.
>
> The same applies to lists, where `{{..2[0]}}` references the first item of the parent two levels up.

The equivalent relative paths for the previous example would be:

![Relative placeholders](/assets/reference/content/definition/relative-placeholders.png)

> **Example: Content definition with relative paths**
>
> Here is the content definition for the previous example:
>
> ```pmsjson
> {
>   "type": "structure",
>   "attributes": {
>     "message": {
>       "type": "text",
>       "value": {
>         "type": "static",
>         "value": "Get {{..discount}}% off with code {{..coupon}}!"
>       }
>     },
>     "promotion": {
>       "type": "structure",
>       "attributes": {
>         "discount": {
>           "type": "number",
>           "value": {
>             "type": "static",
>             "value": 30
>           }
>         },
>         "coupon": {
>           "type": "text",
>           "value": {
>             "type": "static",
>             "value": "SAVE{{..discount}}"
>           }
>         }
>       }
>     }
>   }
> }
> ```

## Fallback values

Lastly, you can optionally provide a fallback value for cases where the reference points to a missing or non-primitive value. When not specified, it defaults to an empty string.

For example, you can use the placeholder `{{description | No description}}` to fall back to *"No description"* (or any other text) in the absence of the `description` attribute, assuming it is optional.

> **Whitespace trimming**
>
> Leading and trailing whitespace are trimmed from the fallback value to prevent unwanted spaces in the final content.

To use a literal character in your default value, you can escape it with a backslash `\`. For example, you can use `{{description | \ No description}}` to force a space before the default value.

It is important to note that placeholder behavior depends on the value type of the referenced attribute:

- **Text**: the reference is inserted into the final value as is.
- **Number**: the number is formatted and converted to text, following the same behavior as in JavaScript.
- **Boolean**: the reference is rendered as either `true` or `false`.
- **Other values**: the reference is silently ignored and becomes an empty string in the final value.

## Dynamic values

You can also use placeholders to insert user-specific values into your content.

> **Private attributes**
>
> You can use [private attributes](/reference/content/schema/types/structure#attribute-private-prop) to provide dynamic values without including them in the final content.

For example, you can use a placeholder to insert the user's name in a greeting message with the help of another attribute:

![Dynamic placeholders](/assets/reference/content/definition/dynamic-placeholders.png)

In this example, the result will be either *"Welcome, John!"* or *"Welcome, guest!"* depending on the user's context.

> **Example: Content definition with dynamic values**
>
> Here is the content definition for the previous example:
>
> ```pmsjson
> {
>   "type": "structure",
>   "attributes": {
>     "message": {
>       "type": "text",
>       "value": {
>         "type": "static",
>         "value": "Welcome, {{variable}}!"
>       }
>     },
>     "variable": {
>       "type": "text",
>       "value": {
>         "type": "dynamic",
>         "default": "guest",
>         "nullable": true,
>         "expression": "user's name"
>       }
>     }
>   }
> }
> ```

> **Scale plan**
>
> This feature is available only to accounts on the Scale plan. See the [pricing page](https://croct.com/pricing) for more information.

## Examples

Here are some examples of placeholders for your quick reference:

| Placeholder                     | Description                                                                                  |
| ------------------------------- | -------------------------------------------------------------------------------------------- |
| `{{attribute}}`                 | Insert a root attribute called `attribute`.                                                  |
| `{{attribute.child}}`           | Insert a nested attribute called `child` from a root attribute called `attribute`.           |
| `{{attribute \\| fallback}}`    | Insert a root attribute called `attribute`, or a `fallback` value if it does not exist.      |
| `{{attribute[n]}}`              | Insert the nth item of a list attribute called `attribute` at the root level.                |
| `{{..attribute}}`               | Insert a sibling attribute called `attribute`.                                               |
| `{{..attribute.child}}`         | Insert a nested attribute called `child` from a sibling attribute called `attribute`.        |
| `{{..[n]}}`                     | Insert the nth item of the parent list.                                                      |
| `{{..[n].attribute}}`           | Insert an attribute called `attribute` from the nth item of the parent list.                 |
| `{{..i.attribute}}`             | Insert a parent attribute called `attribute` that is `i` levels above the current attribute. |
| `{{..i[n]}}`                    | Insert the nth item of the parent list that is `i` levels above the current attribute.       |
| `{{attribute \\| \\ fallback}}` | Escape a leading space in the default value.                                                 |
