在 Shopify Flow 中使用 Liquid 变量
Liquid 变量是在 Liquid 中定义的占位符,在工作流运行时,它们会被替换为来自 GraphQL Admin API 的值。变量可以描述您的工作流所涉及的客户、订单和产品的属性,例如订单号、订单价格或客户姓名。变量可用于条件,从而控制工作流中的逻辑,或输出行动中的数据。
在此页面上
使用 Liquid 在工作流中添加变量
您可以使用 Liquid 将变量添加到任何包含添加变量链接的文本字段中。请点击相关字段下方的添加变量链接,然后从列表中选择一个变量。

添加变量列表中的变量已经过筛选,因此您只能使用当前步骤之前的步骤(例如触发器)返回的变量。例如,订单已创建触发器提供可作为变量插入的 Admin API 中的订单和商店资源。从列表中选择变量后,它会以格式正确的 Liquid 添加到文本框中。
您还可以在文本字段中直接编写 Liquid。例如,您可以使用变量 {{ order.name }} 来显示 Shopify 后台中的订单字符串,例如 order-123。
由于 Flow 使用 Admin API 检索用于 Liquid 的数据,因此变量语法使用驼峰式命名法。驼峰式命名法变量的第一个单词以小写字母开头,后续单词以大写字母开头,例如 firstName 或 canMarkAsPaid。例如,要访问产品的创建日期,请输入 {{ product.createdAt }}。如果您在不使用驼峰式命名法的 Shopify 模板中使用 Liquid 语法,则需要输入 {{ product.created_at }}。
条件和迭代 Liquid 标记
Liquid 标记可与变量结合使用以执行以下函数:
- 编写条件语句,例如确定订单总额是否大于 100 美元。
- 遍历对象列表,例如输出订单中每个订单项目的数据。
您可以使用 Liquid 标记 来编写这些语句并遍历对象。
例如,如果订单总额大于 100 美元,以下 Liquid 将显示订单号:
{% if order.totalPriceSet.shopMoney.amount > 100 %}
Order number: {{ order.name }}
{% endif %}您还可以使用 for 循环来遍历对象列表,例如订单的订单项目。例如,以下 Liquid 将显示订单中每个订单项目的名称:
{% for li in order.lineItems %}
{{ li.title }}
{% endfor %}Flow 支持以下 Liquid 条件(或控制流)标记:
- if
- unless
- elsif/else
- case/when
- and/or(多个条件)
Flow 还支持以下 Liquid 迭代标记:
对变量应用筛选器
您可以使用筛选器在 Liquid 中转换变量数据。Flow 支持所有开源 Liquid 筛选器。
例如,以下 Liquid 会从订单名称中删除前缀并输出剩余部分:{{ order.name | remove: "Order-" }}
在筛选器中使用 Liquid 变量的注意事项
在使用筛选器转换变量之前,请查看以下注意事项:
- Flow 不支持某些筛选器可用的点表示法。例如,Flow 支持
{{ order.lineItems | size }},但不支持{{ order.lineItems.size }}。 - Flow 不支持对元字段使用点表示法。例如,您无法使用
{{ order.metafields.custom.hold_note }}。您必须按照示例中的概述循环遍历元字段。 - Flow 不支持使用索引来访问列表中的项目。例如,您无法使用
{{ order.lineItems[0].title }}。您必须按照示例中的概述循环遍历订单项目。
日期筛选器
除了标准的 Liquid 筛选器外,Flow 还提供日期筛选器以获取相对于另一日期的日期,以支持计划时间触发器和获取数据功能。这些筛选器是:date_minus 和 date_plus。例如:
- 返回未来一天的日期:
{{ "now" | date_plus: "1 day" }} - 返回过去一天的日期:
{{ "now" | date_minus: "1 day" }}
这些筛选器接受 second、minute、day、week、month 和 year 作为持续时间单位,包括单数形式(例如 second)和复数形式(例如 seconds)。您还可以提供以下类型的可自定义单位:
- 一个表示秒数的整数:
{{ "now" | date_minus: 3600 }},其中 3600 等于 1 小时。 - 一个 ISO8601 持续时间字符串:
{{ "now" | date_minus: "P1Y2D" }},其中P1Y2D表示 1 年零 2 天。
加密筛选器
Flow 提供了加密筛选器,可用于进行哈希处理和创建基于哈希的消息验证代码 (HMAC)。这些筛选器可用于创建唯一识别码、校验和,或与需要特定哈希格式的第三方系统集成。
哈希筛选器
Shopify Flow 支持以下类型的哈希筛选器:
对于常规哈希处理目的和新的实现,您应使用 blake3,因为它与旧算法相比具有卓越的性能和安全性。但是,为了与第三方系统兼容,还提供了 sha256、sha1 和 md5。
用法示例:
{{ "hello world" | blake3 }} 会返回“hello world”的 BLAKE3 哈希值。
HMAC 筛选器
若要使用密钥创建 HMAC,请使用以下受支持的筛选器之一:
hmac_sha256- 创建一个使用 SHA-256 的 HMAC。hmac_sha1- 创建一个使用 SHA-1 的 HMAC。
用法示例:
- 基本:
{{ "message" | hmac_sha256: "secret_key" }} - 使用密钥(推荐):
{{ "message" | hmac_sha256: secrets.api_key }}
在 Shopify Flow 中将变量与 Liquid 配合使用的示例
要更好地了解如何使用 Liquid 变量,请参考以下示例:
- 输出资源的 URL
- 将标签列表转换为元字段
- 为订单编写动态电子邮件消息
- 为库存不足的产品编写动态电子邮件消息
- 编写动态电子邮件消息以将欺诈性订单通知给员工
- 使用 for 循环输出订单的订单项目
- 使用 for 循环输出订单的订单项目以及其他信息
- 通过将 for 循环与 if 语句相结合来输出某些订单项目
输出资源的 URL
您想输出工作流中涉及的客户、订单和产品的 URL。
# Output the base Admin URL for your store
https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}
# Assign the base Admin url to a variable named base_url:
{%- capture base_url -%}https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}{%- endcapture -%}
# Customer from a Customer trigger:
{{ base_url }}/customers/{{ customer.legacyResourceId }}
# Customer without the base_url:
https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}/customers/{{ customer.legacyResourceId }}
# Customer from an Order trigger:
{{ base_url }}/customers/{{ order.customer.legacyResourceId }}
# Order:
{{ base_url }}/orders/{{ order.legacyResourceId }}
# Product:
{{ base_url }}/products/{{ product.legacyResourceId }}
# Product Variant:
{{ base_url }}/products/{{ product.legacyResourceId }}/variants/{{ productVariant.legacyResourceId }}
# Example showing a clickable link in HTML, making use of the URL:
<a href="{{ base_url }}/products/{{ product.legacyResourceId }}">{{ product.title }}</a>将标记列表转换为元字段
您想将一组标记转换为作为单行文本字段列表的元字段。您可以使用将产品添加到商店触发器创建工作流,并使用更新产品元字段操作。在更新产品元字段操作的值部分,您需要添加以下 liquid 代码。此示例假定您只需在创建产品时设置一次值,并且该产品有两个相关标记:color:red 和 color:orange。
| 输入 | 输出 |
|---|---|
| ["red","orange"] |
为订单编写动态电子邮件消息
您想创建一个工作流,以便在客户在订单上的花费超过 500 美元时向员工发送电子邮件。您可以使用已创建订单触发器创建工作流,设置一个条件(如果订单总额超过 500 美元,该条件为 true),并使用发送内部电子邮件操作。在发送内部电子邮件操作的消息部分,您可以使用以下变量。
| 输入 | 输出 |
|---|---|
| 请向 Jeanne Dupont (jeanne@example.com) 发送一封个人感谢信,感谢她下了一笔 763.42 美元的订单。 |
为库存不足的产品编写动态电子邮件消息
您决定在产品库存不足并且需要订购更多库存时通知员工。您创建一个以库存数量已更改触发器开头的工作流,并设置一个条件(如果之前的库存数量小于或等于 10,则该条件为 true)。在发送内部电子邮件操作的消息部分,您可以使用以下变量。
| 输入 | 输出 |
|---|---|
| 请再订购高腰紧身裤 - 黑色。请发送电子邮件至 owner@example.com 以验证他们是否已收到采购订单。 |
编写动态电子邮件消息以将欺诈性订单通知给员工
您想取消具有高风险级别的订单,但希望由员工手动取消订单。您创建一个以已创建订单触发器开头的工作流,并设置一个条件(如果订单的风险级别等于“高”,则该条件为 true)。在发送内部电子邮件操作的消息部分,您可以使用以下变量。
| 输入 | 输出 |
|---|---|
| 我们的 Shopify 商店收到了一笔具有高欺诈风险的订单。我们希望在将此订单投入生产前立即将其取消: #1001 Dupont, Jeanne jeanne@example.com 请确认新的订单状态。谢谢! |
使用 for 循环输出订单的订单项目
收到订单后,发送包含所订购产品的消息会很有用。您可以通过使用 for loop 来执行此操作,它会重复执行一个代码块。支持变量的文本字段也支持for 循环和 forloop 对象。
例如,您想创建一个工作流程来返回订单中所有 SKU 和数量的列表。在发送内部电子邮件操作的消息部分,您可以使用以下变量。
| 输入 | 输出 |
|---|---|
| 订单摘要: 8987097979 (50) 8877778887 (3) 888998898B (1) |
使用 for 循环输出订单的订单项目和附加信息
您决定向电子邮件中添加更多信息,包括产品名称、SKU、每件商品的价格以及客户的发货信息。在发送内部电子邮件操作的消息部分,您可以使用以下变量。
| 输入 | 输出 |
|---|---|
| 订单摘要: 产品:高腰紧身裤 - 黑色 SKU:8987097979 单价:$8.49 数量:5 产品:运动袜 - 蓝色 SKU:888998898B 单价:$5.61 数量:2 |
通过 for 循环和 if 语句输出部分订单项目
您需要跟踪由特定厂商供应的已售商品。在发送内部电子邮件操作的消息部分,您可以使用以下变量,并在您的 for 循环中添加一个 if 语句。
| 输入 | 输出 |
|---|---|
| Acme 产品已售出: 产品名称:高腰紧身裤 - 黑色 SKU:8987097979 |
Shopify Flow 中的复杂数据对象
Flow 允许您访问 GraphQL Admin API 中的几乎所有数据。这包括列表和对象等复杂数据对象。但是,您可以使用这些对象执行的操作存在一些限制。本节概述了这些限制,并提供了有关如何使用这些对象的示例。
您应循环访问列表并仅包括您想要的字段,而不是直接调用列表和对象。
例如,若要调用特定字段,请使用以下格式,而不是直接调用 {{ order.lineItems }}。这些示例包含通过直接调用列表或对象会包含的所有字段。请复制并粘贴您需要的字段。
文本
{% for li in order.lineItems %}
{% comment %}li.contract - omitted{% endcomment %}
{% for ca in li.customAttributes %}
{{ ca.key }}
{{ ca.value }}
{% endfor %}
{% for da in li.discountAllocations %}
{{ da.allocatedAmountSet.presentmentMoney.amount }}
{{ da.allocatedAmountSet.presentmentMoney.currencyCode }}
{{ da.allocatedAmountSet.shopMoney.amount }}
{{ da.allocatedAmountSet.shopMoney.currencyCode }}
{% endfor %}
{{ li.discountedTotalSet.presentmentMoney.amount }}
{{ li.discountedTotalSet.presentmentMoney.currencyCode }}
{{ li.discountedTotalSet.shopMoney.amount }}
{{ li.discountedTotalSet.shopMoney.currencyCode }}
{{ li.discountedUnitPriceSet.presentmentMoney.amount }}
{{ li.discountedUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.discountedUnitPriceSet.shopMoney.amount }}
{{ li.discountedUnitPriceSet.shopMoney.currencyCode }}
{% comment %}li.duties - omitted {% endcomment %}
{{ li.fulfillableQuantity }}
{{ li.fulfillmentService.callbackUrl }}
{{ li.fulfillmentService.fulfillmentOrdersOptIn }}
{{ li.fulfillmentService.handle }}
{{ li.fulfillmentService.id }}
{{ li.fulfillmentService.inventoryManagement }}
{% comment %}rest of location omitted{% endcomment %}
{{ li.fulfillmentService.location.name }}
{{ li.fulfillmentService.productBased }}
{{ li.fulfillmentService.serviceName }}
{% for sm in li.fulfillmentService.shippingMethods %}
{{ sm.code }}
{{ sm.label }}
{% endfor %}
{{ li.fulfillmentService.type }}
{{ li.fulfillmentStatus }}
{{ li.id }}
{{ li.image.altText }}
{{ li.image.height }}
{{ li.image.id }}
{% comment %}li.image.metafield omitted{% endcomment %}
{% comment %}li.image.privateMetafield omitted{% endcomment %}
{{ li.image.width }}
{{ li.merchantEditable }}
{{ li.name }}
{{ li.nonFulfillableQuantity }}
{{ li.originalTotalSet.presentmentMoney.amount }}
{{ li.originalTotalSet.presentmentMoney.currencyCode }}
{{ li.originalTotalSet.shopMoney.amount }}
{{ li.originalTotalSet.shopMoney.currencyCode }}
{{ li.originalUnitPriceSet.presentmentMoney.amount }}
{{ li.originalUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.originalUnitPriceSet.shopMoney.amount }}
{{ li.originalUnitPriceSet.shopMoney.currencyCode }}
{% comment %}rest of product omitted{% endcomment %}
{{ li.product.title }}
{{ li.quantity }}
{{ li.refundableQuantity }}
{{ li.requiresShipping }}
{{ li.restockable }}
{{ li.sellingPlan.name }}
{{ li.sku }}
{% for tl in li.taxLines %}
{{ tl.priceSet.presentmentMoney.amount | json }}
{{ tl.priceSet.presentmentMoney.currencyCode | json }}
{{ tl.priceSet.shopMoney.amount | json }}
{{ tl.priceSet.shopMoney.currencyCode | json }}
{{ tl.rate | json }}
{{ tl.ratePercentage | json }}
{{ tl.title | json }}
{% endfor %}
{{ li.taxable }}
{{ li.title }}
{{ li.totalDiscountSet.presentmentMoney.amount }}
{{ li.totalDiscountSet.presentmentMoney.currencyCode }}
{{ li.totalDiscountSet.shopMoney.amount }}
{{ li.totalDiscountSet.shopMoney.currencyCode }}
{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode }}
{{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode }}
{{ li.unfulfilledQuantity }}
{% comment %}rest of variant omitted{% endcomment %}
{{ li.variant.title }}
{{ li.variantTitle }}
{{ li.vendor }}
{% endfor %}
json
{
"lineItems": [
{% for li in order.lineItems %}
{% if forloop.first != true %},{% endif %}
{
"contract": {
{% comment %}rest of contract omitted{% endcomment %}
"id": {{ li.contract.id | json }}
},
"customAttributes": [
{% for ca in li.customAttributes %}
{% if forloop.first != true %},{% endif %}
{
"key":{{ ca.key | json }},
"value":{{ ca.value | json }}
}
{% endfor %}
],
"discountAllocations": [
{% for da in li.discountAllocations %}
{% if forloop.first != true %},{% endif %}
"allocatedAmountSet": {
"presentmentMoney" : {
"amount": {{ da.allocatedAmountSet.presentmentMoney.amount | json }},
"currencyCode": {{ da.allocatedAmountSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ da.allocatedAmountSet.shopMoney.amount | json }},
"currencyCode": {{ da.allocatedAmountSet.shopMoney.currencyCode | json }}
}
}
{% endfor %}
],
"discountedTotalSet": {
"presentmentMoney" : {
"amount": {{ li.discountedTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.discountedTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.discountedTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.discountedTotalSet.shopMoney.currencyCode | json }}
}
},
"discountedUnitPriceSet": {
"presentmentMoney" : {
"amount": {{ li.discountedUnitPriceSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.discountedUnitPriceSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.discountedUnitPriceSet.shopMoney.amount | json }},
"currencyCode": {{ li.discountedUnitPriceSet.shopMoney.currencyCode | json }}
}
},
"duties": [
{% for duty li.duties %}
{% if forloop.first != true %},{% endif %}
{
{% comment %}rest of duties omitted{% endcomment %}
"id": {{ duty.id | json }}
}
{% endfor %}
],
"fulfillableQuantity": {{ li.fulfillableQuantity | json }},
"fulfillmentService": {
"callbackUrl":{{ li.fulfillmentService.callbackUrl | json }},
"fulfillmentOrdersOptIn": {{ li.fulfillmentService.fulfillmentOrdersOptIn | json }},
"handle": {{ li.fulfillmentService.handle | json }},
"id": {{ li.fulfillmentService.id | json }},
"inventoryManagement": {{ li.fulfillmentService.inventoryManagement | json }},
{% comment %}fulfillmentService.inventoryManagement - omitted {% endcomment %}
"productBased": {{ li.fulfillmentService.productBased | json }},
"serviceName": {{ li.fulfillmentService.serviceName | json }},
"shippingMethods": [
{% for sm in li.fulfillmentService.shippingMethods %}
{% if forloop.first != true %},{% endif %}
{
"code": {{ sm.code | json }},
"label": {{ sm.label | json }}
}
{% endfor %}
],
"type": {{ li.fulfillmentService.type | json }}
},
"fulfillmentStatus": {{ li.fulfillmentStatus | json }},
"id": {{ li.id | json }},
"image": {
"altText": {{ li.image.altText | json }},
"height": {{ li.image.height | json }},
"id": {{ li.image.id | json }},
{% comment %}li.image.metafield omitted{% endcomment %}
{% comment %}li.image.privateMetafield omitted{% endcomment %}
"width":{{ li.image.width | json }}
},
"merchantEditable": {{ li.merchantEditable | json }},
"name": {{ li.name | json }},
"nonFulfillableQuantity": {{ li.nonFulfillableQuantity | json }},
"originalTotalSet": {
"presentmentMoney" : {
"amount": {{ li.originalTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.originalTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.originalTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.originalTotalSet.shopMoney.currencyCode | json }}
}
},
"originalUnitPriceSet": {
"presentmentMoney" : {
"amount": {{ li.originalUnitPriceSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.originalUnitPriceSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.originalUnitPriceSet.shopMoney.amount | json }},
"currencyCode": {{ li.originalUnitPriceSet.shopMoney.currencyCode | json }}
}
},
"product": {
{% comment %}rest of Product omitted{% endcomment %}
"title": {{ li.product.title | json }}
},
"quantity": {{ li.quantity | json }},
"refundableQuantity": {{ li.refundableQuantity | json }},
"requiresShipping": {{ li.requiresShipping | json }},
"restockable": {{ li.restockable | json }},
"sellingPlan": {
"name": {{ li.sellingPlan.name | json }}
},
"sku": {{ li.sku | json }},
"taxLines": [
{% for tl in li.taxLines %}
{% if forloop.first != true %},{% endif %}
{
"priceSet": {
"presentmentMoney" : {
"amount": {{ tl.priceSet.presentmentMoney.amount | json }},
"currencyCode": {{ tl.priceSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ tl.priceSet.shopMoney.amount | json }},
"currencyCode": {{ tl.priceSet.shopMoney.currencyCode | json }}
}
},
"rate": {{ tl.rate | json }},
"ratePercentage": {{ tl.ratePercentage | json }},
"title": {{ tl.title | json }}
}
{% endfor %}
],
"taxable":{{ li.taxable | json }},
"title":{{ li.title | json }},
"totalDiscountSet": {
"presentmentMoney" : {
"amount": {{ li.totalDiscountSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.totalDiscountSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.totalDiscountSet.shopMoney.amount | json }},
"currencyCode": {{ li.totalDiscountSet.shopMoney.currencyCode | json }}
}
},
"unfulfilledDiscountedTotalSet": {
"presentmentMoney" : {
"amount": {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.unfulfilledDiscountedTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode | json }}
}
},
"unfulfilledOriginalTotalSet": {
"presentmentMoney" : {
"amount": {{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.unfulfilledOriginalTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode | json }}
}
},
"unfulfilledQuantity": {{ li.unfulfilledQuantity | json }},
"variant": {
{% comment %}rest of variant omitted {% endcomment %}
"title": {{ li.variant.title | json }}
},
"variantTitle": {{ li.variantTitle | json }},
"vendor": {{ li.vendor | json }}
}
{% endfor %}
]
}