在此頁面上:瞭解如何使用Handlebars反複運算語法,從內容資料來源(例如事件、自訂動作回應和資料集查詢)重複執行陣列,以在訊息中顯示動態清單。
瞭解如何使用Handlebars反複運算語法來顯示訊息中各種來源的動態資料清單,包括事件、自訂動作回應和其他內容資料。
概觀 overview
在訊息個人化期間,Journey Optimizer可讓您存取來自多個來源的內容資料。 您可以使用原生管道(電子郵件、推播、簡訊)中的Handlebars語法,從這些來源重複處理陣列,以顯示動態內容,例如產品清單、建議或其他重複元素。
可用的內容來源:
本指南會說明如何在訊息中逐一檢視陣列,以及如何在設定歷程活動時使用陣列。 從Handlebars反複專案語法開始,以瞭解訊息個人化基本概念,或跳至使用歷程運算式中的陣列,以瞭解如何將陣列資料傳遞至自訂動作和資料集查詢。
Handlebars反複專案語法 syntax
Handlebars提供{{#each}} 協助程式來反複處理陣列。 基本語法為:
關鍵點:
- 將
arrayPath取代為您的陣列資料路徑 - 將
item取代為您偏好的任何變數名稱(例如,product、response、element) - 使用
{{item.propertyName}}存取每個專案的屬性 - 您可以巢狀內嵌多重層級陣列的多個
{{#each}}區塊
反複處理事件資料 event-data
當您的歷程由事件觸發時,事件資料可供使用。 這對於顯示歷程開始時所擷取的資料非常有用,例如購物車內容、訂單專案或表單提交。
事件的內容路徑
<event_ID>:您在歷程中設定的事件唯一ID<fieldPath>:事件結構描述中欄位或陣列的路徑
1697323153),請在運算式路徑中以反引號(`)將其換行。 若沒有反引號,PQL剖析器會引發語法錯誤。| code language-handlebars |
|---|
|
範例:來自事件的購物車專案
如果您的事件結構描述包含productListItems陣列(標準XDM格式),您可以顯示購物車內容,如下列範例所詳述。
| code language-handlebars |
|---|
|
範例:事件中的巢狀陣列
對於巢狀結構,請使用巢狀{{#each}}區塊。
| code language-handlebars |
|---|
|
深入瞭解最佳實務中的巢狀結構。
反複處理自訂動作回應 custom-action-responses
自訂動作回應包含從外部API呼叫傳回的資料。 這對於顯示您系統中的即時資訊非常有用,例如忠誠度點數、產品推薦、詳細目錄狀態或個人化優惠。
自訂動作的內容路徑
<actionName>:您在歷程中設定的自訂動作名稱<fieldPath>:回應承載中欄位或陣列的路徑
範例:來自API的產品建議
若要反複運算自訂動作傳回的一系列產品建議,並將它們顯示為訊息中的個別卡片,請參閱下列範例。
API回應:
| code language-json |
|---|
|
訊息個人化:
| code language-handlebars |
|---|
|
範例:自訂動作的巢狀陣列
若要反複處理包含巢狀陣列(一個物件陣列,其中每個物件都包含另一個陣列)的自訂動作回應,請參閱以下範例。 此示範使用巢狀{{#each}}回圈來存取多個層級的資料。
API回應:
| code language-json |
|---|
|
訊息個人化:
| code language-handlebars |
|---|
|
如需更複雜的巢狀模式,請參閱最佳實務。
範例:忠誠度層級優點
若要根據忠誠度狀態顯示動態福利,請參閱以下範例。
API回應:
| code language-json |
|---|
|
訊息個人化:
| code language-handlebars |
|---|
|
反複處理資料集查詢結果 dataset-lookup
資料集查詢活動可讓您在歷程執行階段期間,從Adobe Experience Platform資料集擷取資料。 擴充的資料會以陣列形式儲存,並可在訊息中反複顯示。
在本節中進一步瞭解設定資料集查詢活動。 結合事件資料時,資料集查詢特別強大 — 如需實際使用案例,請參閱範例:使用資料集查詢擴充的事件資料。
資料集查詢的內容路徑
<activityID>:資料集查詢活動的唯一IDentities:從資料集擷取的擴充資料陣列
範例:資料集中的產品詳細資料
如果您使用資料集查詢活動根據SKU擷取產品資訊,請參閱以下範例。
資料集查詢組態:
- 查閱金鑰:
list(@event{purchase_event.products.sku}) - 要傳回的欄位:
["SKU", "category", "price", "name"]
訊息個人化:
| code language-handlebars |
|---|
|
範例:使用資料集資料篩選反複專案
若要在反複專案期間篩選資料集查詢結果,並僅顯示符合特定條件的專案(例如,來自特定類別的產品),請在{{#each}}回圈中使用條件{{#if}}陳述式。 請參閱下列範例。
| code language-handlebars |
|---|
|
進一步瞭解最佳實務中的條件式篩選。
範例:從資料集查詢計算總計
若要在疊代資料集查閱結果時計算並顯示總計,請參閱以下範例。
| code language-handlebars |
|---|
|
使用歷程技術屬性 technical-properties
歷程技術屬性可讓您存取有關歷程執行的中繼資料,例如歷程ID和補充識別碼。 在與反複專案模式結合時,這些功能可能會很有用,尤其是根據特定歷程例項篩選陣列時。
可用的技術屬性
範例:使用補充識別碼篩選陣列專案
在事件觸發的具有陣列的歷程中使用補充識別碼時,您可以篩選以僅顯示目前歷程執行個體的相關專案。 進一步瞭解本指南中的補充識別碼。
案例:歷程是由多個預訂所觸發,但您只想要顯示觸發此歷程執行個體之特定預訂(以補充ID識別)的資訊。
| code language-handlebars |
|---|
|
範例:包含用於追蹤的歷程ID
若要在您的訊息中包含歷程ID以進行追蹤,請參閱下列範例。
| code language-handlebars |
|---|
|
合併多個內容來源 combine-sources
您可以將不同來源的資料合併成相同訊息,以建立豐富的個人化體驗。 本節顯示一起使用多個內容來源的實際範例。
您可以合併的內容來源:
範例:具有即時詳細目錄的購物車專案
若要結合事件資料(購物車內容)與自訂動作資料(詳細目錄狀態),請檢視下列範例。
| code language-handlebars |
|---|
|
範例:使用資料集查詢擴充了事件資料
若要結合事件SKU與資料集查詢的詳細產品資訊,請檢視下列範例。
| code language-handlebars |
|---|
|
範例:將多個來源與技術屬性結合
若要將多個內容來源(設定檔資料、事件資料、自訂動作和技術屬性)合併為單一訊息,請檢視下列範例。
| code language-handlebars |
|---|
|
其他內容型別 other-contexts
雖然本指南著重於陣列的疊代,但其他內容型別可用於個人化,通常不需要疊代。 您可以直接存取這些連結,而非透過下列連結:
如需使用這些來源的完整個人化語法和範例,請參閱:
在歷程運算式中使用陣列 arrays-in-journeys
雖然上一節著重於使用Handlebars在訊息個人化中反複處理陣列,您也可以在設定歷程活動時使用陣列。 本節說明如何在Journey運算式中使用來自事件的陣列資料,尤其是將資料傳遞至自訂動作或使用具有資料集查詢的陣列時。
first、all和serializeList之類的函式搭配使用。 在訊息內容中,您使用Handlebars語法搭配{{#each}}回圈。傳遞陣列值至自訂動作引數 arrays-to-custom-actions
設定自訂動作時,您通常需要從事件陣列擷取值,並將它們當成引數傳遞。 本節說明常見模式。
深入瞭解如何在傳遞集合至自訂動作引數。
從陣列擷取單一值
使用案例:從事件陣列取得特定欄位,以作為查詢引數傳遞到GET要求中。
範例案例:從產品清單中擷取價格大於0的第一個SKU。
事件結構描述範例:
| code language-json |
|---|
|
自訂動作組態:
- 在您的自訂動作中,使用型別
string設定查詢引數(例如sku) - 將其標籤為
Variable以允許動態值
動作引數中的歷程運算式:
| code language-javascript |
|---|
|
說明:
@event{YourEventName}:參考您的歷程事件.first(currentEventField.condition):傳回符合條件的第一個陣列專案currentEventField:代表事件陣列中的每個專案,因為您會在其中重複執行.SKU:從相符的專案中擷取SKU欄位- 結果:
"SKU-1"(適用於動作引數的字串)
深入瞭解集合管理函式中的first函式。
從陣列建立值清單
使用案例:建立以逗號分隔的ID清單,以作為查詢引數傳遞(例如,/products?ids=sku1,sku2,sku3)。
自訂動作組態:
- 使用型別
string設定查詢引數(例如ids) - 將其標籤為
Variable
歷程運算式:
| code language-javascript |
|---|
|
說明:
-
.all(currentEventField.condition):傳回符合條件的所有陣列專案(傳回清單) -
currentEventField:代表事件陣列中的每個專案,因為您會在其中重複執行 -
.SKU:專案清單以僅包含SKU值 -
serializeList(list, delimiter, addQuotes):將清單加入字串",":使用逗號做為分隔符號true:在每個字串元素周圍加上引號
-
結果:
"SKU-1,SKU-3"(適用於查詢引數)
進一步瞭解:
自訂動作的集合處理包含在將集合傳遞至自訂動作引數中。
傳遞物件陣列至自訂動作
使用案例:傳送要求內文中的完整物件陣列(針對POST或GET含內文)。
要求內文範例:
| code language-json |
|---|
|
自訂動作組態:
- 在要求內文中將
products定義為型別listObject - 將其標籤為
Variable - 定義物件欄位:
id、name、price、color(每個欄位都可以對應)
歷程畫佈設定:
-
在進階模式中,設定集合運算式:
code language-javascript @event{YourEventName.commerce.productListItems.all(currentEventField.priceTotal > 0)} -
在集合對應UI中:
- 將
id對應→productListItems.SKU - 將
name對應→productListItems.name - 將
price對應→productListItems.priceTotal - 將
color對應→productListItems.color
- 將
Journey Optimizer會建構符合動作裝載結構的物件陣列。
| note |
|---|
| NOTE |
使用事件陣列時,請使用currentEventField來參考每個專案。 對於資料來源集合(Adobe Experience Platform),請使用currentDataPackField。 對於自訂動作回應集合,請使用currentActionField。 |
深入瞭解將集合傳遞至自訂動作引數。
使用陣列進行資料集查詢 arrays-with-dataset-lookup
使用資料集查詢活動時,您可以傳遞一組值作為查詢索引鍵,以擷取擴充的資料。
範例:查詢事件陣列中所有SKU的產品詳細資料。
資料集查詢組態:
在查閱索引鍵欄位中,使用list()將陣列路徑轉換為清單:
| code language-javascript |
|---|
|
這會建立要在資料集中查詢的所有SKU值清單。 結果可在context.journey.datasetLookup.<activityID>.entities以陣列形式提供,您可以在訊息中反複查詢(請參閱反複查詢資料集查詢結果)。
限制和模式 array-limitations
在歷程中使用陣列時,請注意下列限制:
在歷程流程中陣列上無動態回圈
歷程無法建立動態回圈,因為陣列中的每個專案會多次執行一個動作節點。 這是刻意為防止出現失控的效能問題。
您無法執行的動作:
- 為每個陣列專案動態執行一次自訂動作
- 根據陣列長度建立多個歷程分支
改為建議的模式:
深入瞭解護欄和限制。
陣列大小考量
大型陣列可能會影響歷程效能:
- 事件陣列:將事件裝載總數保持在50KB以下
- 自訂動作回應:回應裝載應小於100KB
- 資料集查閱結果:限制查閱金鑰和傳回實體的數目
完成範例:自訂動作的事件陣列 complete-example
以下是完整的工作流程,說明如何將事件陣列與自訂動作搭配使用。
案例:當使用者放棄購物車時,請將購物車資料傳送至外部建議API以取得個人化建議,然後在電子郵件中顯示這些建議。
步驟1:設定自訂動作
建立自訂動作「GetCartRecommendations」:
- 方法: POST
- URL:
https://api.example.com/recommendations - 要求內文:
| code language-json |
|---|
|
- 將
cartItems標示為型別listObject和Variable - 定義欄位:
sku(字串)、price(數字)、quantity(整數)
深入瞭解設定自訂動作。
步驟2:設定回應承載
在自訂動作中設定回應:
| code language-json |
|---|
|
深入瞭解使用API呼叫回應。
步驟3:在歷程中連線動作
-
在購物車放棄事件後,新增自訂動作
-
在
cartItems集合的進階模式中:code language-javascript @event{cartAbandonment.commerce.productListItems.all(currentEventField.quantity > 0)} -
對應集合欄位:
sku→productListItems.SKUprice→productListItems.priceTotalquantity→productListItems.quantity
步驟4:在電子郵件中使用回應
在您的電子郵件內容中,重複建議:
| code language-handlebars |
|---|
|
步驟5:測試您的設定
在執行即時歷程之前,請使用動作設定中的「傳送測試請求」功能來測試自訂動作,以驗證建置的請求和值。
深入瞭解疑難排解您的自訂動作。
最佳做法 best-practices
重複上下文資料時,請遵循這些最佳實務,以建立可維護、高效能的個人化。
使用描述性變數名稱
選擇可清楚指出您正在反複處理的專案的變數名稱。 這可讓您的程式碼更容易閱讀及維護。 深入瞭解個人化語法:
| code language-handlebars |
|---|
|
回圈中的運算式片段
在{{#each}}回圈中使用運算式片段時,請注意,您無法傳遞回圈範圍的變數做為片段引數。 不過,片段可以存取在片段以外的訊息內容中定義的全域變數。
支援的模式 — 使用全域變數:
| code language-handlebars |
|---|
|
片段可以參照globalDiscount,因為它已在訊息中全域定義。
不支援 — 傳遞回圈變數:
| code language-handlebars |
|---|
|
因應措施:將個人化邏輯直接包含在回圈中,而非使用片段,或呼叫回圈外的片段。
深入瞭解如何在回圈🔗中使用運算式片段,包括詳細範例和其他因應措施。
處理空白陣列
當陣列為空時,請使用{{else}}子句來提供遞補內容。 深入瞭解協助程式函式:
| code language-handlebars |
|---|
|
與條件式協助程式結合
在條件式內容的回圈中使用{{#if}}。 深入瞭解條件式規則,並檢視自訂動作回應與資料集查詢區段中的範例。
| code language-handlebars |
|---|
|
限制效能的反複專案
對於大型陣列,請考慮限制迭代次數:
| code language-handlebars |
|---|
|
存取陣列中繼資料
Handlebars在回圈中提供特殊變數,有助於進階反複運算模式:
@index:目前的反複專案索引(0型)@first:第一個反複專案為True@last:最後一個反複專案為True
| code language-handlebars |
|---|
|
@index、@first、@last)只能在訊息個人化的{{#each}}回圈中使用。 若要在Journey運算式中使用陣列(例如在傳遞至自訂動作之前從陣列取得第一個專案),請使用陣列函式,例如head、first或all。 如需詳細資訊,請參閱在歷程運算式中使用陣列。疑難排解 troubleshooting
反複專案發生問題? 本節涵蓋常見問題和解決方案。
未顯示陣列
問題:您的陣列反複專案未顯示任何內容。
語法錯誤
問題:運算式驗證失敗或未轉譯訊息。
常見錯誤:
- 遺失結尾標籤:每個
{{#each}}都必須有{{/each}}。 請檢閱Handlebars反複專案語法以取得正確結構。 - 不正確的變數名稱:請確定在整個區塊中一律使用變數名稱。 如需命名慣例,請參閱最佳實務。
- 不正確的路徑分隔符號:使用點(
.)而不使用斜線或其他字元
運算式片段無法在回圈中運作
問題:運算式片段在{{#each}}回圈中使用時未顯示預期的內容,或顯示空白/未預期的輸出。
可能的原因和解決方案:
-
嘗試傳遞回圈變數做為引數:運算式片段無法接收回圈範圍的變數(例如目前的反複專案等)做為引數。 這是已知的限制。
解決方案:使用下列變通方法之一:
- 在訊息中定義片段可存取的全域變數
- 直接在回圈中包含個人化邏輯,而非使用片段
- 如果不需要回圈特定的資料,請呼叫回圈外部的片段
-
片段需要無法使用的引數:如果您的片段設計來接收特定的輸入引數,當這些引數無法從回圈中傳遞時,將無法正常運作。
解決方案:重新建構您的方法,以使用片段可以存取的全域變數。 如需範例,請參閱最佳實務 — 回圈中的運算式片段。
-
不正確的變數範圍:片段可能正在嘗試參考只存在於回圈範圍內的變數。
解決方案:定義片段在訊息層級(回圈外)需要的任何變數,讓這些變數可全域存取。
深入瞭解如何在回圈🔗中使用運算式片段,包括詳細的說明、範例和建議的模式。
測試您的反複專案
使用歷程測試模式驗證您的反複專案。 使用自訂動作或資料集查詢時,這一點尤其重要:
- 以測試模式開始您的歷程
- 使用範例資料觸發事件或自訂動作
- 檢查訊息預覽以驗證反複專案是否正確顯示
- 檢閱測試模式記錄檔是否有任何錯誤(請參閱自訂動作測試模式記錄檔)
相關主題 related-topics
Personalization基本知識: 開始使用個人化 | 新增個人化 | Personalization語法 | 協助程式函式 | 建立條件式規則
歷程組態: 關於事件 | 設定自訂動作 | 將集合傳遞至自訂動作引數 | 在自訂動作中使用API呼叫回應 | 疑難排解您的自訂動作 | 在歷程中使用Adobe Experience Platform資料 | 在歷程中使用補充識別碼 | 護欄和限制 | 測試您的歷程
歷程運算式函式: 進階運算式編輯器 | 集合管理函式 (第一個、全部、最後一個) | 列出函式 (serializeList、篩選、排序) | 陣列函式 (頭、尾)
Personalization使用案例: 購物車放棄電子郵件 | 訂單狀態通知
郵件設計: 開始使用電子郵件設計 | 建立推播通知 | 建立SMS訊息 | 預覽和測試您的內容
This section contains structured knowledge intended to support interpretation, retrieval, and question answering related to this topic.
For complete understanding, this information should be combined with the documentation on this page. Neither source is intended to stand alone; the page describes the feature, while this section provides additional context that helps disambiguate terminology, intent, applicability, and constraints.
- TL;DR: This page explains how to use Handlebars
{{#each}}syntax to loop over arrays from contextual sources — events, custom action responses, dataset lookups, and technical properties — in message personalization, and how to work with arrays in journey expression syntax when configuring journey activities.
Intents:
- Iterate over event array data (e.g., cart items, order items) in message personalization using
{{#each}} - Iterate over custom action response arrays (e.g., product recommendations) in messages
- Iterate over dataset lookup result arrays in messages
- Combine data from multiple contextual sources in a single personalized message
- Pass array values to custom action parameters using journey expression syntax
- Use arrays as lookup keys in Dataset Lookup activities
- Apply best practices for empty array fallbacks, variable naming, performance, and expression fragment scoping
Glossary:
- Handlebars: A templating language used in Journey Optimizer message personalization for iteration (
{{#each}}) and conditional rendering ({{#if}}). (product-specific) {{#each}}helper: Handlebars syntax for iterating over an array; each iteration exposes the current item via a named variable (e.g.,|product|). (product-specific)- Contextual data: Data available at message send time from journey sources — events, custom action responses, dataset lookups, and journey technical properties — as opposed to static profile attributes. (product-specific)
currentEventField: A reference used in journey expressions (not Handlebars) to refer to each item in an event array during filtering or mapping operations.currentActionField: Used in journey expressions to refer to each item in a custom action response collection.currentDataPackField: Used in journey expressions to refer to each item in a data source collection.serializeList: A journey expression function that converts a list of values into a delimited string (e.g., comma-separated), suitable for use as a query parameter.- Supplemental identifier: A journey-level identifier that distinguishes concurrent journey instances triggered by the same profile; used to filter an array to the item relevant to the current instance.
Guardrails:
- Journeys cannot create dynamic loops where one action node executes multiple times per array item — this is by design to prevent performance issues. Pass the entire array or a serialized list to a single custom action instead.
- Keep event payloads under 50KB total.
- Custom action response payloads should be under 100KB.
- Limit the number of dataset lookup keys and returned entities for performance.
- Expression fragments cannot receive loop-scoped variables (e.g., the current
{{#each}}iteration item) as parameters — this is a known limitation. Use global variables or inline logic instead. - Numeric event IDs must be wrapped in backticks in expression paths (e.g.,
context.journey.events.`1697323153`.fieldName); without backticks, the PQL parser raises a syntax error.
Terminology:
- Canonical name: Handlebars iteration — variants:
{{#each}}loop, each loop, array iteration - Do not confuse: Handlebars
{{#each}}syntax (used in message content for iteration and display) ≠ journey expression syntax (used in journey activity configuration — uses functions likefirst,all,serializeList) - Do not confuse:
currentEventField(journey expressions over event arrays) ≠currentActionField(custom action response collections) ≠currentDataPackField(data source collections) - Do not confuse:
@index/@first/@last(Handlebars special variables, only available within{{#each}}loops in message content) ≠first/headfunctions (journey expression functions for extracting single items, used in journey activity configuration)
FAQ:
- Q: What is the difference between Handlebars syntax and journey expression syntax when working with arrays? — Handlebars
{{#each}}is used in message content for iteration and display. Journey expression syntax — using functions likefirst,all, andserializeList— is used in journey activity configuration (e.g., custom action parameters, conditions). They are distinct syntaxes used in different contexts. - Q: Can I loop a journey action node so it executes once per array item? — No. Journeys cannot create dynamic loops that execute an action node multiple times per item. Instead, pass the entire array or a serialized list to a single custom action that processes all items, or use external aggregation.
- Q: Can I pass the current loop item to an expression fragment inside a
{{#each}}loop? — No. Expression fragments cannot receive loop-scoped variables as parameters. Use global variables defined outside the loop, or include the personalization logic directly within the loop instead of using a fragment. - Q: How do I display fallback content when an array is empty? — Use the
{{else}}clause within the{{#each}}block. Content inside{{else}}is rendered when the array has no items. - Q: What do
@index,@first, and@lastmean inside a{{#each}}loop? — These are special Handlebars variables available only within{{#each}}loops in message content:@indexis the 0-based current iteration index,@firstis true for the first iteration, and@lastis true for the last iteration.