跳转到主要内容
Liquid 是 OneSignal 支持的模板语言,用于跨渠道个性化消息,包括邮件、推送、短信、应用内和 Live Activities。它使用标签、过滤器和条件语句来动态自定义消息内容。 要了解更多 Liquid 语法信息,请参阅官方 Liquid 文档

基本语法

Liquid 使用两种主要的语法结构:
  1. 输出标签{{ ... }} — 显示变量或对象中的数据。
  2. 逻辑标签{% ... %} — 执行条件语句或循环。

条件语句

运算符

  • ==, !=, >, <, >=, <=
  • and, or
  • contains (string or array)
liquid
{% if true or false and false %}
  这是真的。
{% endif %}

ifelsifelse

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

unless

liquid
{% unless level == "1" %}
  恭喜你通过了第一关!
{% endunless %}

过滤器

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

default

如果属性为空或不存在,则分配默认值。
liquid
Hello {{ first_name | default: "there" }}.

date

date 过滤器将时间戳转换为另一种日期格式。此语法的格式与 strftime 相同。输入使用与 Ruby 的 Time.parse 相同的格式。 使用标签将日期设置为以秒为单位的 unix 时间戳。这允许同时使用 liquid 语法个性化和时间运算符进行细分。例如,标签可能是:bill_due : 1687968776
liquid
{{ bill_due | date: "%a, %b %d, %y" }}
{{ "now" | date: "%Y-%m-%d %H:%M" }}
Result
Wed, Jun 28, 23
liquid
{{ bill_due | date: "%Y" }}
Result
2023
如果字符串包含格式良好的日期,日期格式化可以处理字符串。
liquid
{{ "March 14, 2016" | date: "%b %d, %y" }}
Result
Mar 14, 16
要获取当前时间,请将特殊单词 now(或 today)与日期过滤器一起传递。
liquid
此消息发送于 {{ "now" | date: "%Y-%m-%d %H:%M" }}。
Result
此消息发送于 2022-11-02 14:39。
当前时间将根据消息发送给接收者的时间在消息中呈现。如果您正在测试消息, 您将看到当前时间为测试消息发送的时间。

capitalize

此过滤器将字符串的第一个字符大写,并将其余字符转换为小写。
liquid
{{ "my GREAT title" | capitalize }}
Result
My great title

round

此过滤器将数字四舍五入到最接近的整数,或者如果传递了一个数字作为参数,则四舍五入到指定的小数位数。
liquid
{{ 1.2 | round }}
  {{ 2.7 | round }}
{{ 183.357 | round: 2 }}
Result
1
3
183.36

pluralize

此过滤器根据给定的数字返回字符串的单数或复数形式。数字必须是整数,可以作为字符串提供。必须同时提供字符串的单数和复数形式。
liquid
{{ 1 | pluralize: "singular", "plural" }}
{{ 2 | pluralize: "singular", "plural" }}
1 {{ 1 | pluralize: "person", "people" }}
2 {{ 2 | pluralize: "person", "people" }}
2 {{ "2" | pluralize: "person", "people" }}
Result
singular
plural
1 person
2 people
2 people

迭代

for 循环

重复执行代码块。有关 for 循环中可用属性的完整列表,请参阅 Liquid for 循环文档
liquid
{% for product in message.custom_data.products %}
  - {{ product.name }}
  {% else %}
    抱歉,我们的所有产品都已售完。
  {% endfor %}
Request Body
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "custom_data": {
    "products": [
      { "name": "Sweater" },
      { "name": "Hat" },
      { "name": "Shirt" }
    ]
  }
}
Result
- Sweater
- Hat
- Shirt

(如果 message.custom_data.products 为空)
抱歉,我们的所有产品都已售完。
虽然功能强大且灵活,但在某些罕见情况下,在 Liquid 语法中使用 for 循环可能 导致通知传递性能不佳。请注意您对 for 循环的使用。另请注意,我们禁止在 几个推送频道字段中使用 for 循环:contentsheadingssubtitleapns_alerturl

limitoffset

将循环限制为指定的迭代次数。例如,如果您只想在消息中显示 4 个产品,您可以使用限制和偏移量来指定显示的产品数量。
Data
great_numbers = [1,2,3,4,5,6]
liquid
{% for number in great_numbers limit:2 %}
  {{ number }}
{% endfor %}
Result
1 2
要在指定索引开始循环,请添加偏移值:
Data
great_numbers = [1,2,3,4,5,6]
liquid
{% for number in great_numbers limit: 3 %}
  {{ number }}
{% endfor %}

{% for number in great_numbers limit: 3 offset: 3 %}
  {{ number }}
{% endfor %}
Result
1 2 3
4 5 6

where

创建一个数组,仅包含具有给定属性值的对象,或默认情况下任何真值。 在此示例中,假设您有一个产品列表,并且想要单独显示您的厨房产品。使用 where,您可以创建一个仅包含 typekitchen 的产品的数组。
Data
products = [
  {name:"Vacuum", type:"electronics"},
  {name:"Spatula", type:"kitchen"},
  {name:"Television", type:"electronics"},
  {name:"Garlic press", type:"kitchen"}
]
liquid
所有产品:
{% for product in products %}
- {{ product.name }}
{% endfor %}

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

厨房产品:
{% for product in kitchen_products %}
- {{ product.name }}
{% endfor %}
Result
所有产品:
  - 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 过滤器
liquid
Hello {{ name | default: "there" }}!
Result (name = "Jon")
Hello Jon!
Result (name 为空)
Hello there!
当周围文本、标点符号或句子结构也需要根据变量是否存在而改变时,使用 if/else 条件逻辑
liquid
{% if name %}{{ name }}, shop your favorites!{% else %}Shop your favorites!{% endif %}
Result (name = "Jon")
Jon, shop your favorites!
Result (name 为空)
Shop your favorites!
当句子结构改变时,不要使用 default。例如,{{ name | default: "Shop your favorites" }}, shop your favorites 在 name 为空时会渲染为”Shop your favorites, shop your favorites”。如果回退改变的不仅仅是变量,请使用 if/else

如何控制空白和换行?

使用连字符:{{- ... -}}{%- ... -%} 来修剪周围的空白。 更多详情请参阅空白控制

如何处理用户生成的内容?

将用户生成的文本包装在 {% raw %}{% endraw %} 中以防止 Liquid 解析。参见 “raw” 语法
{
  "contents": {
    "en": "{% raw %} Your user-generated content with invalid characters like {{ {% endraw %}"
  }
}

相关页面

消息个性化

所有个性化选项的概述,包括 Liquid、Data Feeds 和自定义事件。

Data Feeds

在发送时从您的 API 将实时数据拉入消息中。

标签

在用户上存储键值对,用于分段和 Liquid 个性化。

模板

创建内置 Liquid 个性化的可重用消息模板。