> ## 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.

# 使用 Liquid 语法

> 使用 Liquid 标签、过滤器、条件语句和循环个性化电子邮件、推送、短信、应用内和 Live Activity 内容——由 OneSignal 数据源（如标签、属性、自定义数据和 Data Feeds）提供支持。

Liquid 是 OneSignal 支持的模板语言，用于跨渠道个性化消息，包括邮件、推送、短信、应用内和 Live Activities。它使用标签、过滤器和条件语句来动态自定义消息内容。

要了解更多 Liquid 语法信息，请参阅[官方 Liquid 文档](https://shopify.github.io/liquid/basics/introduction/)。

***

## 基本语法

Liquid 使用两种主要的语法结构：

1. **输出标签**：`{{ ... }}` — 显示变量或对象中的数据。
2. **逻辑标签**：`{% ... %}` — 执行条件语句或循环。

***

## 条件语句

### 运算符

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

```text liquid theme={null}
{% if true or false and false %}
  这是真的。
{% 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" %}
  恭喜你通过了第一关！
{% endunless %}
```

***

## 过滤器

使用 `{{ variable | filter }}` 应用过滤器来调整数据显示方式。

### `default`

如果属性为空或不存在，则分配默认值。

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

### `date`

date 过滤器将时间戳转换为另一种日期格式。此语法的格式与 [strftime](https://strftime.net/) 相同。输入使用与 Ruby 的 [Time.parse](https://ruby-doc.org/stdlib-2.4.1/libdoc/time/rdoc/Time.html) 相同的格式。

使用标签将日期设置为以秒为单位的 unix 时间戳。这允许同时使用 liquid 语法个性化和[时间运算符](./time-operators)进行细分。例如，标签可能是：`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
```

如果字符串包含格式良好的日期，日期格式化可以处理字符串。

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

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

要获取当前时间，请将特殊单词 `now`（或 `today`）与日期过滤器一起传递。

```text liquid theme={null}
此消息发送于 {{ "now" | date: "%Y-%m-%d %H:%M" }}。
```

```text Result theme={null}
此消息发送于 2022-11-02 14:39。
```

<Info>
  当前时间将根据消息发送给接收者的时间在消息中呈现。如果您正在测试消息，
  您将看到当前时间为测试消息发送的时间。
</Info>

### `capitalize`

此过滤器将字符串的第一个字符大写，并将其余字符转换为小写。

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

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

### `round`

此过滤器将数字四舍五入到最接近的整数，或者如果传递了一个数字作为参数，则四舍五入到指定的小数位数。

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

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

### `pluralize`

此过滤器根据给定的数字返回字符串的单数或复数形式。数字必须是整数，可以作为字符串提供。必须同时提供字符串的单数和复数形式。

```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
```

***

## 迭代

### `for` 循环

重复执行代码块。有关 `for` 循环中可用属性的完整列表，请参阅 [Liquid `for` 循环文档](https://shopify.github.io/liquid/tags/iteration/)。

```text liquid theme={null}
{% for product in message.custom_data.products %}
  - {{ product.name }}
  {% else %}
    抱歉，我们的所有产品都已售完。
  {% 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

(如果 message.custom_data.products 为空)
抱歉，我们的所有产品都已售完。
```

<Warning>
  虽然功能强大且灵活，但在某些罕见情况下，在 Liquid 语法中使用 `for` 循环可能
  导致通知传递性能不佳。请注意您对 `for` 循环的使用。另请注意，我们禁止在
  几个推送频道字段中使用 `for` 循环：`contents`、`headings`、`subtitle`、
  `apns_alert` 和 `url`
</Warning>

### `limit` 和 `offset`

将循环限制为指定的迭代次数。例如，如果您只想在消息中显示 4 个产品，您可以使用限制和偏移量来指定显示的产品数量。

```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
```

要在指定索引开始循环，请添加偏移值：

```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`

创建一个数组，仅包含具有给定属性值的对象，或默认情况下任何真值。

在此示例中，假设您有一个产品列表，并且想要单独显示您的厨房产品。使用 `where`，您可以创建一个仅包含 `type` 为 `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}
所有产品：
{% for product in products %}
- {{ product.name }}
{% endfor %}

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

厨房产品：
{% for product in kitchen_products %}
- {{ product.name }}
{% endfor %}
```

```text Result theme={null}
所有产品：
  - Vacuum
  - Spatula
  - Television
  - Garlic press

厨房产品：
- Spatula
- Garlic press
```

***

## 字符串操作

使用字符串过滤器调整标签值或内联字符串在消息中的显示方式。

| 命令              | 描述                         | 示例                                                       | 示例输出        |
| --------------- | -------------------------- | -------------------------------------------------------- | ----------- |
| `replace`       | 用另一个字符串替换子字符串。             | `{{ 'hello world' \| replace: 'world', 'there' }}`       | hello there |
| `capitalize`    | 将字符串的第一个字母大写。              | `{{ 'hello' \| capitalize }}`                            | Hello       |
| `upcase`        | 将字符串转换为大写。                 | `{{ 'hello' \| upcase }}`                                | HELLO       |
| `downcase`      | 将字符串转换为小写。                 | `{{ 'HELLO' \| downcase }}`                              | hello       |
| `strip`         | 从字符串中删除前导和尾随空白。            | `{{ ' hello ' \| strip }}`                               | hello       |
| `strip_html`    | 从字符串中删除所有 HTML 标签。         | `{{ '<p>hello</p>' \| strip_html }}`                     | hello       |
| `truncate`      | 将字符串缩短到指定长度，如果需要则添加省略号（…）。 | `{{ 'This is a long sentence' \| truncate: 10 }}`        | This is a…  |
| `truncatewords` | 在一定数量的单词后截断字符串。            | `{{ 'This is a long sentence' \| truncatewords: 2 }}`    | This is…    |
| `replace_first` | 替换子字符串的第一次出现。              | `{{ 'hello world' \| replace_first: 'world', 'there' }}` | hello there |
| `prepend`       | 在另一个字符串的开头添加字符串。           | `{{ 'world' \| prepend: 'hello ' }}`                     | hello world |
| `append`        | 在另一个字符串的末尾添加字符串。           | `{{ 'hello' \| append: ' world' }}`                      | hello world |
| `lstrip`        | 从字符串中删除前导空白。               | `{{ ' hello' \| lstrip }}`                               | hello       |
| `rstrip`        | 从字符串中删除尾随空白。               | `{{ 'hello ' \| rstrip }}`                               | hello       |

***

## 常见问题

### 为什么替换不起作用？

* 应用内消息不支持属性替换。
* 使用"发送测试消息"时标签替换不起作用。
* 标签键必须是字母数字，或使用 \_ 和 -（不能有句点或空格）。
* 替换不会在预览模式中显示 — 发送真实消息进行测试。

### 何时应该使用 `default` 而不是 `if/else`？

当只有变量值需要回退而周围文本保持不变时，使用 **`default` 过滤器**。

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

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

```text Result (name 为空) theme={null}
Hello there!
```

当周围文本、标点符号或句子结构也需要根据变量是否存在而改变时，使用 **`if/else` 条件逻辑**。

```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 为空) theme={null}
Shop your favorites!
```

<Warning>
  当句子结构改变时，不要使用 `default`。例如，`{{ name | default: "Shop your favorites" }}, shop your favorites` 在 name 为空时会渲染为"Shop your favorites, shop your favorites"。如果回退改变的不仅仅是变量，请使用 `if/else`。
</Warning>

### 如何控制空白和换行？

使用连字符：`{{- ... -}}`、`{%- ... -%}` 来修剪周围的空白。
更多详情请参阅[空白控制](https://shopify.github.io/liquid/basics/whitespace/)。

### 如何处理用户生成的内容？

将用户生成的文本包装在 `{% raw %}` 和 `{% endraw %}` 中以防止 Liquid 解析。参见 ["raw" 语法](https://shopify.dev/docs/api/liquid/tags/raw)。

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

***

## 相关页面

<Columns cols={2}>
  <Card title="消息个性化" icon="wand-magic-sparkles" href="./message-personalization">
    所有个性化选项的概述，包括 Liquid、Data Feeds 和自定义事件。
  </Card>

  <Card title="Data Feeds" icon="database" href="./data-feeds">
    在发送时从您的 API 将实时数据拉入消息中。
  </Card>

  <Card title="标签" icon="tag" href="./add-user-data-tags">
    在用户上存储键值对，用于分段和 Liquid 个性化。
  </Card>

  <Card title="模板" icon="file-lines" href="./templates">
    创建内置 Liquid 个性化的可重用消息模板。
  </Card>
</Columns>
