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

# Uso de sintaxis Liquid

> Personaliza el contenido de email, push, SMS, in-app y Live Activity con etiquetas, filtros, condicionales y bucles Liquid — impulsado por fuentes de datos de OneSignal como etiquetas, propiedades, datos personalizados y Data Feeds.

Liquid es un lenguaje de plantillas soportado por OneSignal para personalizar mensajes a través de canales incluyendo email, push, SMS, in-app y Live Activities. Usa etiquetas, filtros y condicionales para personalizar dinámicamente el contenido de mensajes.

Para aprender más sobre la sintaxis Liquid, consulta la [documentación oficial de Liquid](https://shopify.github.io/liquid/basics/introduction/).

***

## Sintaxis básica

Liquid usa dos estructuras de sintaxis principales:

1. **Etiquetas de salida**: `{{ ... }}` — Muestra datos de una variable u objeto.
2. **Etiquetas de lógica**: `{% ... %}` — Ejecuta declaraciones condicionales o bucles.

***

## Condicionales

### Operadores

* `==`, `!=`, `>`, `<`, `>=`, `<=`
* `and`, `or`
* `contains` (cadena o array)

```text liquid theme={null}
{% if true or false and false %}
  This is true.
{% endif %}
```

### `if`, `elsif`, `else`

```text liquid theme={null}
{%- assign userLang = subscription.language -%}
{% if userLang == "es" -%}
Hola {{ first_name }}!
{%- elsif userLang == "fr" -%}
Bonjour {{ first_name }}!
{%- else -%}
Hello {{ first_name }}!
{%- endif %}
```

### `unless`

```text liquid theme={null}
{% unless level == "1" %}
  Great job getting past the first level!
{% endunless %}
```

***

## Filtros

Aplica filtros usando `{{ variable | filter }}` para ajustar cómo se muestran los datos.

### `default`

Asigna un valor predeterminado si la propiedad está vacía o no existe.

```text liquid theme={null}
Hello {{ first_name | default: "there" }}.
```

### `date`

El filtro date convierte una marca de tiempo en otro formato de fecha. El formato para esta sintaxis es el mismo que [strftime](https://strftime.net/). La entrada usa el mismo formato que [Time.parse](https://ruby-doc.org/stdlib-2.4.1/libdoc/time/rdoc/Time.html) de Ruby.

Establece fechas como una marca de tiempo unix en segundos con tags. Esto permite el uso tanto de personalización con sintaxis liquid como de segmentación con [Operadores de tiempo](./time-operators). Por ejemplo, un tag podría verse así: `bill_due : 1687968776`

```text liquid theme={null}
{{ bill_due | date: "%a, %b %d, %y" }}
{{ "now" | date: "%Y-%m-%d %H:%M" }}
```

```text Result theme={null}
Wed, Jun 28, 23
```

```text liquid theme={null}
{{ bill_due | date: "%Y" }}
```

```text Result theme={null}
2023
```

El formato de fecha funciona en cadenas si contienen fechas bien formateadas.

```text liquid theme={null}
{{ "March 14, 2016" | date: "%b %d, %y" }}
```

```text Result theme={null}
Mar 14, 16
```

Para obtener la hora actual, pasa la palabra especial `now` (o `today`) junto con el filtro date.

```text liquid theme={null}
This message was sent at {{ "now" | date: "%Y-%m-%d %H:%M" }}.
```

```text Result theme={null}
This message was sent at 2022-11-02 14:39.
```

<Info>
  La hora actual se renderizará en el mensaje según cuándo se envíe el mensaje
  al destinatario. Si estás probando el mensaje, verás la hora actual
  como cuando se envió el mensaje de prueba.
</Info>

### `capitalize`

Este filtro hace que el primer carácter de una cadena esté en mayúscula y convierte los caracteres restantes a minúsculas.

```text liquid theme={null}
{{ "my GREAT title" | capitalize }}
```

```text Result theme={null}
My great title
```

### `round`

Este filtro redondea un número al entero más cercano, o, si se pasa un número como argumento, a ese número de decimales.

```text liquid theme={null}
{{ 1.2 | round }}
  {{ 2.7 | round }}
{{ 183.357 | round: 2 }}
```

```text Result theme={null}
1
3
183.36
```

### `pluralize`

Este filtro devuelve la forma singular o plural de una cadena basándose en un número dado. El número debe ser un número entero y puede proporcionarse como cadena. Deben proporcionarse tanto la forma singular como la plural de una cadena.

```text liquid theme={null}
{{ 1 | pluralize: "singular", "plural" }}
{{ 2 | pluralize: "singular", "plural" }}
1 {{ 1 | pluralize: "person", "people" }}
2 {{ 2 | pluralize: "person", "people" }}
2 {{ "2" | pluralize: "person", "people" }}
```

```text Result theme={null}
singular
plural
1 person
2 people
2 people
```

***

## Iteración

### Bucles `for`

Ejecuta repetidamente un bloque de código. Para una lista completa de atributos disponibles dentro de un bucle `for`, consulta la [documentación del bucle `for` de Liquid](https://shopify.github.io/liquid/tags/iteration/).

```text liquid theme={null}
{% for product in message.custom_data.products %}
  - {{ product.name }}
  {% else %}
    Sorry, we're sold out of all products.
  {% endfor %}
```

```json Request Body theme={null}
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "custom_data": {
    "products": [
      { "name": "Sweater" },
      { "name": "Hat" },
      { "name": "Shirt" }
    ]
  }
}
```

```text Result theme={null}
- Sweater
- Hat
- Shirt

(Si message.custom_data.products está vacío)
Lo sentimos, estamos sin existencias de todos los productos.
```

<Warning>
  Aunque poderosos y flexibles, el uso de bucles `for` en sintaxis liquid puede
  llevar a un rendimiento deficiente en la entrega de notificaciones en ciertos casos raros. Ten
  cuidado con tu uso de bucles `for`. También ten en cuenta que prevenimos el uso de
  bucles `for` en algunos campos de Canal Push: `contents`, `headings`, `subtitle`,
  `apns_alert`, y `url`
</Warning>

### `limit` & `offset`

Limita el bucle al número especificado de iteraciones. Por ejemplo, si solo quieres mostrar 4 productos en un mensaje, podrías usar Límites y Desplazamientos para especificar el número de productos mostrados.

```text Data theme={null}
great_numbers = [1,2,3,4,5,6]
```

```text liquid theme={null}
{% for number in great_numbers limit:2 %}
  {{ number }}
{% endfor %}
```

```text Result theme={null}
1 2
```

Para comenzar el bucle en el índice especificado, agrega un valor de desplazamiento:

```text Data theme={null}
great_numbers = [1,2,3,4,5,6]
```

```text liquid theme={null}
{% for number in great_numbers limit: 3 %}
  {{ number }}
{% endfor %}

{% for number in great_numbers limit: 3 offset: 3 %}
  {{ number }}
{% endfor %}
```

```text Result theme={null}
1 2 3
4 5 6
```

### `where`

Crea un array que incluye solo los objetos con un valor de propiedad dado, o cualquier valor verdadero por defecto.

En este ejemplo, supón que tienes una lista de productos y quieres mostrar tus productos de cocina por separado. Usando `where`, puedes crear un array que contenga solo los productos que tienen un `type` de `kitchen`.

```text Data theme={null}
products = [
  {name:"Vacuum", type:"electronics"},
  {name:"Spatula", type:"kitchen"},
  {name:"Television", type:"electronics"},
  {name:"Garlic press", type:"kitchen"}
]
```

```text liquid theme={null}
All products:
{% for product in products %}
- {{ product.name }}
{% endfor %}

{% assign kitchen_products = products | where: "type", "kitchen" %}

Kitchen products:
{% for product in kitchen_products %}
- {{ product.name }}
{% endfor %}
```

```text Result theme={null}
All products:
  - Vacuum
  - Spatula
  - Television
  - Garlic press

Kitchen products:
- Spatula
- Garlic press
```

***

## Manipulación de cadenas

Aplica filtros de cadena para ajustar cómo se muestran los valores de etiquetas o cadenas en línea en los mensajes.

| Comando         | Descripción                                                                                      | Ejemplo                                                  | Salida de ejemplo |
| --------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | ----------------- |
| `replace`       | Reemplaza una subcadena con otra cadena.                                                         | `{{ 'hello world' \| replace: 'world', 'there' }}`       | hello there       |
| `capitalize`    | Capitaliza la primera letra de una cadena.                                                       | `{{ 'hello' \| capitalize }}`                            | Hello             |
| `upcase`        | Convierte una cadena a mayúsculas.                                                               | `{{ 'hello' \| upcase }}`                                | HELLO             |
| `downcase`      | Convierte una cadena a minúsculas.                                                               | `{{ 'HELLO' \| downcase }}`                              | hello             |
| `strip`         | Elimina espacios en blanco iniciales y finales de una cadena.                                    | `{{ ' hello ' \| strip }}`                               | hello             |
| `strip_html`    | Elimina todas las etiquetas HTML de una cadena.                                                  | `{{ '<p>hello</p>' \| strip_html }}`                     | hello             |
| `truncate`      | Acorta una cadena a una longitud especificada, agregando puntos suspensivos (…) si es necesario. | `{{ 'This is a long sentence' \| truncate: 10 }}`        | This is a…        |
| `truncatewords` | Trunca una cadena después de un cierto número de palabras.                                       | `{{ 'This is a long sentence' \| truncatewords: 2 }}`    | This is…          |
| `replace_first` | Reemplaza la primera ocurrencia de una subcadena.                                                | `{{ 'hello world' \| replace_first: 'world', 'there' }}` | hello there       |
| `prepend`       | Agrega una cadena al principio de otra cadena.                                                   | `{{ 'world' \| prepend: 'hello ' }}`                     | hello world       |
| `append`        | Agrega una cadena al final de otra cadena.                                                       | `{{ 'hello' \| append: ' world' }}`                      | hello world       |
| `lstrip`        | Elimina espacios en blanco iniciales de una cadena.                                              | `{{ ' hello' \| lstrip }}`                               | hello             |
| `rstrip`        | Elimina espacios en blanco finales de una cadena.                                                | `{{ 'hello ' \| rstrip }}`                               | hello             |

***

## Preguntas frecuentes

### ¿Por qué no funciona la sustitución?

* Los Mensajes In-App no soportan sustitución de propiedades.
* La sustitución de tag no funciona cuando se usa "Send Test Message".
* Las claves de tag deben ser alfanuméricas, o usar \_ y - (sin puntos ni espacios).
* La sustitución no aparece en modo de vista previa — envía un mensaje real para probar.

### ¿Cuándo debo usar `default` en lugar de `if/else`?

Usa el **filtro `default`** cuando solo el valor de la variable necesita un fallback y el texto circundante permanece igual.

```text liquid theme={null}
Hello {{ name | default: "there" }}!
```

```text Result (name = "Jon") theme={null}
Hello Jon!
```

```text Result (name está vacío) theme={null}
Hello there!
```

Usa la **lógica condicional `if/else`** cuando el texto circundante, la puntuación o la estructura de la oración también necesiten cambiar según si existe la variable.

```text liquid theme={null}
{% if name %}{{ name }}, shop your favorites!{% else %}Shop your favorites!{% endif %}
```

```text Result (name = "Jon") theme={null}
Jon, shop your favorites!
```

```text Result (name está vacío) theme={null}
Shop your favorites!
```

<Warning>
  No uses `default` cuando la estructura de la oración cambia. Por ejemplo, `{{ name | default: "Shop your favorites" }}, shop your favorites` renderizaría como "Shop your favorites, shop your favorites" cuando el nombre está vacío. Si el fallback cambia más que solo la variable, usa `if/else`.
</Warning>

### ¿Cómo controlar espacios en blanco y saltos de línea?

Usa guiones: `{{- ... -}}`, `{%- ... -%}` para recortar espacios en blanco circundantes.
Ver [Control de espacios en blanco](https://shopify.github.io/liquid/basics/whitespace/) para más detalles.

### ¿Cómo manejar contenido generado por usuarios?

Envuelve el texto generado por usuarios en `{% raw %}` y `{% endraw %}` para prevenir el análisis de Liquid. Ver [sintaxis "raw"](https://shopify.dev/docs/api/liquid/tags/raw).

```json theme={null}
{
  "contents": {
    "en": "{% raw %} Your user-generated content with invalid characters like {{ {% endraw %}"
  }
}
```

***

## Páginas relacionadas

<Columns cols={2}>
  <Card title="Personalización de mensajes" icon="wand-magic-sparkles" href="./message-personalization">
    Descripción general de todas las opciones de personalización, incluyendo Liquid, Data Feeds y eventos personalizados.
  </Card>

  <Card title="Data Feeds" icon="database" href="./data-feeds">
    Obtén datos en tiempo real de tus APIs en los mensajes en el momento del envío.
  </Card>

  <Card title="Etiquetas" icon="tag" href="./add-user-data-tags">
    Almacena pares clave-valor en usuarios para segmentación y personalización Liquid.
  </Card>

  <Card title="Plantillas" icon="file-lines" href="./templates">
    Crea plantillas de mensajes reutilizables con personalización Liquid integrada.
  </Card>
</Columns>
