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

添加变量列表中的变量将被筛选,以便您只使用当前步骤之前的步骤返回的变量,例如触发器。例如,已创建订单触发器提供 Admin API 中的订单和商店资源,这些资源可以作为变量插入。从列表中选择一个变量后,它将作为格式正确的 Liquid 添加到文本框中。
您还可以直接在文本块中编写 Liquid。例如,您可以使用变量 {{ order.name }}
来显示 Shopify 后台中显示的订单字符串,例如 order-123。
由于 Flow 使用 Admin API 来检索用于 Liquid 的数据,因此变量语法使用“驼峰式命名法”。例如,若要访问产品的创建日期,请输入 {{ 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 还提供日期筛选条件,用于获取相对于其他日期的日期以支持已安排时间触发器和获取数据功能。这些筛选条件包括: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 }}
您还可以提供 ISO8601 持续时间字符串,其中 P1Y2D
表示 1 年零 2 天:{{ "now" | date_minus: "P1Y2D" }}
在筛选条件中使用 Liquid 变量的注意事项
- Flow 不支持适用于某些筛选条件的点符号。例如,Flow 支持
{{ order.lineItems | size }}
,但不支持{{ order.lineItems.size }}
。 - Flow 不支持用于元字段的点符号。例如,您无法使用
{{ order.metafields.custom.hold_note }}
。您必须改为循环遍历示例中列出的元字段。 - Flow 不支持使用索引来访问列表中的项目。例如,您无法使用
{{ order.lineItems[0].title }}
。您必须改为循环遍历示例中列出的订单项目。
示例
为了更好地了解如何使用 Liquid 变量,请考虑以下示例。
输出资源的 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
。
输入 | 输出 |
---|---|
{% capture mf_value %} {%- for tags_item in product.tags -%} {%- if tags_item contains "color:" -%} "{{- tags_item | remove_first: "color:" | strip -}}", {%- endif -%} {%- endfor -%} {% endcapture -%} [{{mf_value | remove_last: ","}}] | ["red","orange"] |
为订单撰写动态电子邮件消息
假设您想创建一个工作流,当客户某个订单的花费金额超过 500 美元时,该工作流会向员工发送电子邮件。您可以创建一个使用已创建订单触发器的工作流,设置在订单总额超过 500 美元时为 true 的条件,然后使用发送内部电子邮件操作。在发送内部电子邮件操作的消息部分中,您可以使用以下变量。
输入 | 输出 |
---|---|
{{ order.customer.firstName }} {{ order.customer.lastName }}({{ order.customer.email }}) 的下单金额为 {{ order.totalPriceSet.shopMoney.amount }} 美元,请向其发送私人感谢备注。 | Jeanne Dupont (jeanne@example.com) 的下单金额为 763.42 美元,请向其发送私人感谢备注。 |
为库存不足的产品撰写动态电子邮件消息
您确定您需要在产品库存不足并且需要下订单以购买更多库存时通知员工。您可以创建一个通过库存数量已更改触发器启动的工作流,并设置在库存数量先验小于或等于 10 时为 true 的条件。在发送内部电子邮件操作的消息部分中,您可以使用以下变量。
输入 | 输出 |
---|---|
请重新订购 {{ product.title }}。向 owner@store.com 发送电子邮件以确认他们已收到采购订单。 | 请重新订购高腰打底裤 - 黑色。向 owner@example.com 发送电子邮件以确认他们已收到采购订单。 |
撰写动态电子邮件消息,以告知员工有关欺诈性订单的信息
您希望取消具有高风险级别的订单,但倾向于让员工手动取消订单。您可以创建通过已创建订单触发器启动的工作流,并设置在订单风险级别等于“高”时为 true 的条件。在发送内部电子邮件操作的消息部分中,您可以使用以下变量。
输入 | 输出 |
---|---|
我们的 Shopify 商店收到一个具有高欺诈风险的订单。我们需要立即取消此订单,避免该订单进入处理流程: {{ order.name }} {{ order.billingAddress.lastName }}, {{ order.billingAddress.firstName }} {{ order.email }} 请确认新的订单状态。谢谢! | 我们的 Shopify 商店收到一个具有高欺诈风险的订单。我们需要立即取消此订单,避免该订单进入处理流程: #1001 Dupont, Jeanne jeanne@example.com 请确认新的订单状态。谢谢! |
使用 for 循环为订单输出商品条目
收到订单时,发送包含订购产品的消息非常有用。您可以使用 for loop
来实现此目的,它可重复执行代码块。支持变量的文本字段也支持 for loop 和 forloop 对象。
例如,您想创建一个工作流,用于返回订单中所有 SKU 和数量的列表。在发送内部电子邮件操作的消息部分中,您可以使用以下变量。
输入 | 输出 |
---|---|
订单摘要: {% for a in order.lineItems %} SKU: {{a.sku}} ({{a.quantity}}), {% endfor %} | 订单摘要: 8987097979 (50) 8877778887 (3) 888998898B (1) |
使用 for 循环为订单输出商品条目,并包含其他信息
您决定要向电子邮件添加更多信息,包括产品名称、SKU、每件商品的价格以及客户的收货信息。在发送内部电子邮件操作的消息部分中,您可以使用以下变量。
输入 | 输出 |
---|---|
订单摘要: {% for a in order.lineItems %} 产品: {{a.title}} SKU: {{a.sku}} 价格(单价): {{a.originalUnitPriceSet.shopMoney.amount}} 美元 数量: {{a.quantity}} {% endfor %} | 订单摘要: 产品: 高腰打底裤 - 黑色 SKU: 8987097979 价格(单价): 8.49 美元 数量: 5 产品: 运动袜 - 蓝色 SKU: 888998898B 价格(单价): 5.61 美元 数量: 2 |
通过组合使用 for 循环和 if 语句输出部分商品条目
您需要跟踪由特定厂商供应的已售出商品。在发送内部电子邮件操作的消息部分中,您可以使用以下变量,并在您的 for loop
中包含 if
语句。
输入 | 输出 |
---|---|
Acme 产品已售出: {% for x in order.lineItems %} {% if x.vendor == 'acme-vendor' %} 产品名称: {{x.title}} SKU: {{x.sku}} {% endif %} {% endfor %} | Acme 产品已售出: 产品名称: 高腰打底裤 - 黑色 SKU: 8987097979 |
Shopify Flow 中的复杂数据对象
Flow 允许您访问 GraphQL Admin API 中的几乎所有数据,包括列表和对象这样的复杂数据对象。但是,您对这些对象执行的操作是有限制的。此部分概述了这些限制,并提供了如何使用这些对象的示例。
您应循环访问列表并仅包含所需字段,而不是直接调用列表和对象。
例如,您不应直接调用 {{ order.lineItems }}
,而是使用以下格式来调用特定字段。这些示例涵盖了直接调用列表或对象时将会包含的所有字段。您可以复制并粘贴所需字段。
Text
{% 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 %}
]
}