Shopify Flow 中的 Liquid 變數
此頁面列印時間為 Sep 18, 2024。如須最新版本,請至 https://help.shopify.com/zh-TW/manual/shopify-flow/reference/variables。
「變數」是執行工作流程時會以特定數值來取代的佔位符。這些變數會描述工作流程中所涉及之顧客、訂單及商品的屬性。舉例來說,訂單編號、訂單金額、顧客名稱等資訊都擁有對應的變數。變數可在條件 中用來控制工作流程的邏輯,或在動作 中輸出資料。
關於 Liquid Liquid 是一種範本語言,用於存取動作中的變數及編寫 Flow 中的程式碼。Flow 使用的 Liquid 變數最符合開放原始碼庫 。Shopify 佈景主題使用 Liquid 的另一個變數 ,但此 Liquid 變數是佈景主題專屬的變數,並包含不只 Flow 支援的篩選條件和標籤,及用於存取變數的不同語法。
Liquid 變數 您可以將 Liquid 變數新增至內含「新增變數 」連結的任何文字欄位之中:點擊相關欄位下方的「新增變數 」連結,然後從清單中選擇一個變數。
「新增變數 」清單中的變數會經過篩選,僅向您顯示早於目前步驟的步驟所回傳的變數,例如觸發條件。例如,「訂單已建立 」觸發條件提供訂單和商店資源,可讓您使用與訂單或商店設定相關的任何變數,這些變數可在 GraphQL Admin API 中存取。從清單中選擇變數之後,該變數會進行適當的格式化,然後新增至文字方塊之中。
您還可以直接在文字方塊中編寫 Liquid。例如,您可以使用變數 {{ order.name }}
在 Shopify 管理介面中顯示訂單字串,例如 order-123。
由於 Flow 使用 GraphQL 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 條件 (或控制流程) 標籤:
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 變數,請參考以下範例。
資源的輸出網址 您想要輸出工作流程中涉及的顧客、訂單和商品等項目的網址。
# 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
。
用於設定單行文字欄位清單的範例 Liquid。
輸入
輸出
{% 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 (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 杜維達,Jeanne jeanne@example.com 請確認新的訂單狀態。謝謝!
使用 for 迴圈輸出訂單的商品項目 收到訂單時,建議您傳送包含訂購商品的訊息。您可以使用重複執行程式碼 for loop
來完成此操作。支援變數的文字欄位也支援 for 迴圈和 for 迴圈物件 。
舉例來說,您想要建立一個工作流程,回傳訂單中所有存貨單位 (SKU) 和數量的清單。在「傳送內部電子郵件 」動作的「訊息 」區段中,您使用以下變數。
用於提供訂單資訊的 For 迴圈範例。
輸入
輸出
訂單摘要: {% for a in order.lineItems %} SKU: {{a.sku}} ({{a.quantity}}), {% endfor %}
訂單摘要: 8987097979 (50) 8877778887 (3) 8889988898B (1)
使用 for 迴圈輸出訂單的商品項目並包含其他資訊 您決定在電子郵件中新增更多資訊,包含商品名稱、SKU、單件品項價格,以及顧客的運送資訊。在「傳送內部電子郵件 」動作的「訊息 」區段中,您使用以下變數。
提供更廣泛訂單資訊的 For 迴圈使用範例。
輸入
輸出
訂單摘要: {% 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
陳述式。
用於為特定廠商提供訂單資訊的 For 迴圈和 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 }}
),在 Liquid 中輸出清單/陣列或物件。設定此限制是因為 GraphQL 可能會回傳過多資料,並導致工作流程失敗。此外,引入新欄位時,此動作可能會中斷一些工作流程。
請不要直接呼叫清單和物件,而是以迴圈執行清單,並僅包含所需欄位。
舉例來說,請勿直接呼叫 {{ 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 %}
{
"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 %}
]
}