在 Shopify Flow 中使用 Liquid 變數
Liquid 變數是在 Liquid 中定義的佔位符,工作流程執行時,系統會將其替換為來自 GraphQL Admin API 的值。變數可描述參與工作流程的顧客、訂單及商品屬性,例如訂單編號、訂單價格或顧客名稱。變數可用於條件以控制工作流程的邏輯,或用於輸出動作的資料。
本頁內容
在工作流程中使用 Liquid 新增變數
只要文字欄位包含 新增變數 連結,您就能使用 Liquid 新增變數。按一下相關欄位下方的 新增變數 連結,然後從清單中選擇變數。

「新增變數」清單中的變數已經過篩選,讓您只能使用目前步驟之前的步驟 (例如觸發條件) 所傳回的變數。以 Order Created 觸發條件為例,它會提供來自 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 tags 來撰寫這些敘述,並對物件進行迭代。
例如,下列 Liquid 會在訂單總額大於 $100 時顯示訂單編號:
{% if order.totalPriceSet.shopMoney.amount > 100 %}
Order number: {{ order.name }}
{% endif %}您也可以使用 for loop 來逐一處理物件清單,例如訂單的商品項目。例如,下列 Liquid 會顯示訂單中每個商品項目的名稱:
{% for li in order.lineItems %}
{{ li.title }}
{% endfor %}Flow 支援下列 Liquid 條件 (或控制流程) 標籤:
- if
- unless
- elsif/else
- case/when
- and/or (多重條件)
Flow 也支援下列 Liquid 迭代標籤:
對變數套用過濾器
您可以在 Liquid 中使用過濾器來轉換變數資料。Flow 支援開放原始碼版本的所有 Liquid filters。
例如,下列 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 還提供日期過濾器,可取得相對於另一日期的時間,以支援 Scheduled time 觸發條件與 Get data 功能。這些過濾器包括: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 }},其中 3,600 相當於 1 小時。 - 一個 ISO8601 duration string:
{{ "now" | date_minus: "P1Y2D" }},其中P1Y2D表示 1 年與 2 天。
密碼學過濾器
Flow 提供適用於 hashing 與建立 Hash-based Message Authentication Codes (HMACs) 的密碼學篩選器。這些篩選器可用來建立唯一識別碼、檢查碼,或與需要特定雜湊格式的第三方系統整合。
雜湊篩選器
Shopify Flow 支援以下類型的雜湊篩選器:
針對一般雜湊用途與新實作,建議使用 blake3,因為相較於較舊的演算法,其效能與安全性更佳。不過,sha256、sha1 與 md5 仍提供,以利與第三方系統相容。
使用範例:
{{ "hello world" | blake3 }} 會回傳「hello world」的 BLAKE3 雜湊值。
HMAC 篩選器
若要使用密鑰建立 HMAC,請使用下列支援的篩選器之一:
hmac_sha256:建立 HMAC using SHA-256。hmac_sha1:建立 HMAC using SHA-1。
使用範例:
- 基本用法:
{{ "message" | hmac_sha256: "secret_key" }} - 使用 secrets (建議):
{{ "message" | hmac_sha256: secrets.api_key }}
在 Shopify Flow 中搭配 Liquid 使用變數的範例
若要進一步瞭解如何使用 Liquid 變數,請參考以下範例:
- Output URLs for resources
- Convert a list of tags to a metafield
- Write a dynamic email message for an order
- Write a dynamic email message for a product that is low in stock
- Write a dynamic email message to notify staff about a fraudulent order
- Output the line items for an order using a for loop
- Output the line items for an order using a for loop with additional information
- Output some line items by combining a for loop with an if statement
輸出資源的網址
您希望輸出工作流程中涉及的顧客、訂單與商品的網址。
# 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>將標籤清單轉換為中繼欄位
您想將一組標籤轉換成一個中繼欄位,其型別為 list of single-line text fields。您使用 Product added to store 觸發條件建立工作流程,並使用 Update product metafield 動作。在 Update product metafield 動作的 Value 區段中,加入下列 Liquid 程式碼。此範例假設您只需在建立商品時設定一次這些值,且該商品有兩個相關標籤:color:red 與 color:orange。
| 輸入 | 輸出 |
|---|---|
| ["red","orange"] |
為訂單撰寫動態電子郵件訊息
您想建立一個工作流程,當顧客在單筆訂單消費超過 $500 時,寄送電子郵件給員工。您使用 Order created 觸發條件建立工作流程,設定當訂單總額高於 $500 時條件為真,並使用 Send internal email 動作。在 Send internal email 動作的 Message 區段中,使用以下變數。
| 輸入 | 輸出 |
|---|---|
| 請寄送一封個人感謝信給 Jeanne Dupont (jeanne@example.com),感謝其下訂 $763.42 的訂單。 |
為庫存不足的商品撰寫動態電子郵件訊息
您決定在商品庫存偏低、需要補貨時通知員工。您以 Inventory quantity changed 觸發條件建立工作流程,並設定當先前的庫存數量小於或等於 10 時條件為真。在 Send internal email 動作的 Message 區段中,使用以下變數。
| 輸入 | 輸出 |
|---|---|
| 請重新訂購 High Waist Leggings - Black。請寄送電子郵件至 owner@example.com,確認他們已收到採購單。 |
撰寫動態電子郵件訊息,通知員工有詐騙訂單
您希望取消高風險等級的訂單,但傾向由員工手動取消。您以 Order created 觸發條件建立工作流程,並設定當訂單的風險等級為高時條件為真。在 Send internal email 動作的 Message 區段中,使用以下變數。
| 輸入 | 輸出 |
|---|---|
| 我們的 Shopify 商店收到一筆具有高詐騙風險的訂單。我們想在送交生產前,立即取消這筆訂單: #1001 Dupont, Jeanne jeanne@example.com 請確認新的訂單狀態。謝謝! |
使用 for 迴圈輸出訂單的商品項目
收到訂單時,傳送一則包含所訂購商品的訊息會很實用。您可以使用 for loop 來達成,其會重複執行一段程式碼區塊。支援變數的文字欄位也支援 for loops and the forloop object。
例如,您想建立一個工作流程,傳回某筆訂單中所有存貨單位 (SKU) 與數量的清單。在 傳送內部電子郵件 動作的 訊息 區段中,請使用下列變數。
| 輸入 | 輸出 |
|---|---|
| 訂單摘要: 8987097979 (50) 8877778887 (3) 888998898B (1) |
使用 for 迴圈輸出訂單的商品項目,並包含額外資訊
您決定在電子郵件中加入更多資訊,包括商品名稱、存貨單位 (SKU)、單價,以及顧客的運送資訊。在 傳送內部電子郵件 動作的 訊息 區段中,請使用下列變數。
| 輸入 | 輸出 |
|---|---|
| 訂單摘要: 商品:High Waist Leggings - Black SKU:8987097979 單價:$8.49 數量:5 商品:Athletic Socks - Blue SKU:888998898B 單價:$5.61 數量:2 |
結合 for 迴圈與 if 陳述式,輸出部分商品項目
您需要追蹤由特定廠商供應的已售出品項。在 傳送內部電子郵件 動作的 訊息 區段中,請使用下列變數,並在 for loop 中加入 if 陳述式。
| 輸入 | 輸出 |
|---|---|
| 售出的 Acme 商品: 商品名稱:High Waist Leggings - Black SKU:8987097979 |
Shopify Flow 中的複雜資料物件
Shopify 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 %}
]
}