パーソナライゼーション構文 personalization-syntax

このページ:​一般的なルール、予約済みのキーワード、タイプ強制、使用可能な名前空間、ベストプラクティスなど、Adobe Journey Optimizer での Handlebars と PQL のパーソナライゼーション構文について説明します。

Journey Optimizer のパーソナライゼーションでは、同じの式で一緒に機能する次の 2 つの補完的な構文が使用されます。

  • Handlebars{{...}})- プロファイル属性のレンダリング、配列のループ、ブロックヘルパーの呼び出しに使用されます。 詳しくは、HandlebarsJS ドキュメントを参照してください。
  • Profile Query Language(PQL){%= ... %})- ビルトイン関数(例:upperCase()formatDate()dateDiff())の呼び出しや、条件式の評価に使用されます。

ランタイムエラーを回避するには、どのコンテキストにいるかを理解することが重要です。 例えば、{{...}} 内に PQL 関数呼び出しを配置すると失敗します。これは、Handlebars が PQL 式として評価するのではなく、ヘルパーとして解決しようとするからです。

例:

ユースケース
構文
プロファイル属性のレンダリング
{{profile.person.name.firstName}}
PQL 関数の呼び出し
{%= upperCase(profile.person.name.firstName) %}
条件付きブロック
{%#if profile.loyalty.tier = "gold"%}...{%/if%}
配列のループ
{{#each profile.orders}}...{{/each}}

属性の構造は、Adobe Experience Platform XDM スキーマで定義されます。 学習を増やす

TIP
日付の書式設定、カウントダウン、条件付きフォールバックなど、これらの構文を実際のシナリオに適用したすぐに使用できる式について詳しくは、パーソナライゼーションのレシピ​ページを参照してください。

構文の一般的なルール general-rules

  • 識別子には、Handlebars 構文用に予約されている次の特殊文字を除く任意の Unicode 文字を使用できます。

    code language-none
    Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~
    
  • 構文では大文字と小文字が区別されます。

  • truefalsenull および undefined​という語は、パス式の最初の部分でのみ使用できます。

  • Handlebars では、{{expression}} から返される値は HTML エスケープ​されています。 式に「&」が含まれている場合、返される HTML エスケープ出力は「&amp;」として生成されます。 Handlebars の値をエスケープしない場合は、「トリプルスタッシュ」を使用します。

    フィールド profile.person.name の値が「Mark & Mary」であるとします。 構文 {{profile.person.name}} には Mark &amp; Mary が表示され、{{{profile.person.name}}} には Mark & Mary が表示されます。

  • リテラル関数の引数に関して、テンプレート言語パーサーはエスケープされない単一のバックスラッシュ(\)記号をサポートしていません。 この文字は、バックスラッシュ(\)記号を追加してエスケープする必要があります。 例:

    {%= regexGroup("abc@xyz.com","@(\\w+)", 1)%}

  • 文字列値内に​ リテラルな二重引用符 ​を含めるには(例:JSON 出力の生成時)、バックスラッシュ(\")でエスケープします。

    code language-handlebars
    { "message": "Hello \"{{profile.person.name.firstName}}\"" }
    

    出力:{ "message": "Hello \"John\"" }

    または、値自体に HTML エンコードしない特殊文字が含まれている場合は、トリプルスタッシュ {{{ }}} を使用して、エスケープされていない HTML を出力します。

予約済みのキーワード reserved-keywords

特定のキーワードは、Profile Query Language(PQL)で予約され、パーソナライゼーション式のフィールド名または変数名として直接使用できません。 XDM スキーマに予約済みのキーワードと一致する名前のフィールドが含まれている場合、式で参照するには、バックティック(`)を使用してエスケープする必要があります。

予約済みのキーワードは次のとおりです。

  • next
  • last
  • this

例:

プロファイルスキーマに next という名前のフィールドがある場合は、バックティックで囲む必要があります。

{{profile.person.`next`.name}}

バックティックがないと、パーソナライゼーションエディターは検証に失敗し、エラーが発生します。

NOTE
予約済みキーワードに対するバックティックエスケープは、{{...}} の Handlebars パスと {%= ... %} の PQL 式の両方に適用されます。これは、これらのキーワードがパス解決レベルで予約されているからです。 これは、バックティックエスケープが PQL 式内でのみサポートされているハイフネーション処理されたフィールド名とは異なります。 ハイフネーション処理された属性キーを参照してください。

特殊属性キーの PQL 構文ルール pql-special-keys

予約済みのキーワード以外にも、PQL 式でバックティックエスケープが必要になるケースが 2 つあります。

ハイフネーション処理された属性キー hyphenated-keys

XDM スキーマに、ハイフン付きのフィールド名(例:my-fieldevent-type)や、数字で始まるまたは数字を含むフィールド名がが含まれている場合は、PQL 式内でキーをバックティックで囲みます。

{%= profile.events.`order-total` > 100 %}
NOTE
バックティックエスケープは、PQL式({%= ... %})内でのみサポートされています。 Handlebars の補間({{...}})ではサポートされていません。 ハイフネーション処理されたフィールド名は {{...}} ブロック(例:{{profile.my-custom-field}})で直接参照できます。バックティック構文のみがそこでエラーになります。

PQL 式でバックティックを使用しない場合、ハイフンは減算演算子として解釈され、PQL 構文エラーが発生します。

コンテキスト属性の数値イベント ID numeric-event-ids

イベント ID が数値(例:1697323153)であるコンテキストイベント属性を参照する場合は、バックティックで囲みます。 これは、formatDate() などの関数内でも適用されます。

{% let ts = formatDate(toDateTime(context.journey.events.`1697323153`.timestamp), "dd/MM/yyyy") %}
{{ts}}

タイプ強制 type-coercion

PQL は強くタイプ付けされています。 値を比較または渡す場合、両方の側を同じタイプにする必要があります。 よくあるケース:

シナリオ
ソリューション
文字列として格納された数値
算術または比較の前に stringToNumber() を使用します。{%= stringToNumber(profile.loyalty.pointsBalance) > 500 %}
文字列として格納された整数
算術の前に string_to_integer() または stringToNumber() を使用します
文字列として格納されたブール値
変換するには、toBool() を使用します。{%= toBool(profile.consents.email.val) = true %}

使用可能な名前空間 namespaces

  • プロファイル

    この名前空間を使用すると、プロファイルスキーマで定義されているすべての属性を参照できます。このスキーマについて詳しくは、Adobe Experience Platform データモデル(XDM)のドキュメントを参照してください。

    属性は、Journey Optimizer のパーソナライゼーションブロックで参照する前に、スキーマで定義しておく必要があります。

    条件でプロファイル属性を活用する方法について詳しくは、この節を参照してください。

    accordion
    サンプルリファレンス
    • {{profile.person.name.fullName}}
    • {{profile.person.name.firstName}}
    • {{profile.person.gender}}
    • {{profile.personalEmail.address}}
    • {{profile.mobilePhone.number}}
    • {{profile.homeAddress.city}}
    • {{profile.faxPhone.number}}
  • オーディエンス

    セグメント化サービスについて詳しくは、このドキュメントを参照してください。

  • オファー

    この名前空間では、既存のオファー決定を参照できます。

    オファーを参照するには、オファーを定義する様々な情報を使用してパスを宣言する必要があります。 このパスの構造は次のようになります。

    offers.Type.[Placement Id].[Activity Id].Attribute

    ここで:

    • offers はオファー名前空間に属するパス式を識別します。
    • Type はオファー表示域のタイプを決定します。 imagehtml および text などの値が使用されます。
    • Placement IdActivity Id は配置とアクティビティの識別子です。
    • Attributes は、オファータイプに依存するオファー固有の属性です。 例:deliveryUrl(画像の場合)

    決定 API とオファー表示域について詳しくは、このページを参照してください。

    すべての参照は、このページで説明されている検証メカニズムを使用して、オファースキーマに対して検証されます

    accordion
    サンプルリファレンス
    • 画像がホストされる場所:

      offers.image.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].deliveryUrl

    • 画像をクリックしたときのターゲット URL:

      offers.image.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].linkUrl

    • 決定エンジンから得られるオファーのテキストコンテンツ:

      offers.text.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].content

    • 決定エンジンから得られるオファーの HTML コンテンツ:

      offers.html.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].content

ヘルパー helpers-all

Handlebars ヘルパーは、パラメーターの後に付けられる単純な識別子です。 各パラメーターは、Handlebars 式です。 これらのヘルパーは、テンプレート内の任意のコンテキストからアクセスできます。

これらのブロックヘルパーは、ヘルパー名の先頭にある # で識別され、対となる同じ名前の / タグで閉じる必要があります。

ブロックは、ブロック開始タグ({{# }})と終了タグ({{/}})を持つ式です。

ヘルパー関数について詳しくは、この節を参照してください。

リテラル型 literal-types

Adobe Journey Optimizer では、次のリテラル型をサポートしています。

リテラル
定義
文字列
1 つ以上の文字で構成され、二重引用符で囲まれたデータタイプです。
例:"prospect""jobs""articles"
ブール
true か false のいずれかであるデータタイプです。
整数
整数を表すデータタイプです。 正、負、ゼロのいずれかです。
例:-2010412
配列
他のリテラル値のグループとして構成されるデータ型です。 複数の値を区切る場合は、角括弧で囲んでグループ化し、カンマで区切ります。
メモ:配列内の項目のプロパティに直接アクセスすることはできません。
例:[1, 4, 7]["US", "FR"]
CAUTION
xEvent 変数は、パーソナライズ式では使用できません。 xEvent を参照すると、検証エラーが発生します。

ベストプラクティス best-practices

パーソナライゼーション式を作成する前に、これらの構文ルールを確認します。 ほとんどのランタイムエラーは、Handlebars と PQL のコンテキストを混在させることから発生します。

正しい条件付きブロック構文を使用する

常に {%#if%}{%else if%}{%else%}{%/if%} を使用します。 {% if %}{% elseif %}{% endif %} 構文はサポートされていません。

{%#if profile.loyalty.tier = "gold"%}
Gold member content
{%else if profile.loyalty.tier = "silver"%}
Silver member content
{%else%}
Default content
{%/if%}

{{...}} Handlebars ブロック内で PQL 関数を呼び出さない

{{...}} は Handlebars 変数とヘルパーのみを解決します。PQL は評価されません。 upperCase() などの PQL 関数を {{...}} で囲むと、「ヘルパーが見つかりませんでした」エラーが発生します。 代わりに、{%= ... %} 呼び出しを使用します。

不正確
正確
{{upperCase(cleanName)}}
{%= upperCase(cleanName) %}

{{#each}}{%#if%} を組み合わせる際は、名前付きのループエイリアスを使用する

this.field は Handlebars レンダラーによって解決されますが、{%#if%} 条件内の PQL 評価基準では解決されません。 as |item| を使用して名前付きエイリアスを定義し、両方のコンテキストでフィールドを解決できるようにします。

{{#each profile.orders as |order|}}
  {%#if order.status = "pending"%}
  Order {{order.id}} is pending.
  {%/if%}
{{/each}}

ループの前に、PQL 関数の結果を変数に割り当てる

topN などの PQL UDF は、{{#each}} 内から直接呼び出すことはできません。 最初に {% let %} でこれらを評価し、その結果を反復処理します。

{% let topOrders = topN(profile.orders, price, 3) %}
{{#each topOrders}}
  {{this.name}} — {{this.price}}&euro;
{{/each}}

関数呼び出しの繰り返しを避けるために {% let %} を使用する

計算された値が複数回必要な場合は、変数に格納します。 これにより、読みやすさが向上し、冗長な評価を防ぐことができます。

{% let cleanName = replaceAll(profile.person.name.firstName, "[^a-zA-Z]", "") %}
Hi {{cleanName}}, your code is: WELCOME-{%= upperCase(cleanName) %}

dateDiff に正しい引数の順序を使用する

dateDiff(start, end) は、先に早い日付を指定します。 今後の日付までの残り日数を計算するには、現在の日付を最初の引数として渡します。

{% let daysLeft = dateDiff(getCurrentZonedDateTime(), stringToDate(profile.loyalty.expiryDate)) %}

PQL での等価比較には、== ではなく、= を使用する

PQL では、等価性の判定に単一の = 演算子を使用します。 == を使用すると、構文エラーが発生します。

ハイフネーション処理されたフィールド名にはバックティックを使用する - PQL 式でのみ

XDM スキーマフィールド名にハイフン(例:order-total)が含まれる場合は、ハイフンが減算演算子として解析されないように、フィールド名をバックティックで囲みます。 これは、{%= ... %} PQL 式内でのみサポートされ、{{...}} Handlebars ブロック内ではサポートされていません。

{%= profile.events.`order-total` > 100 %}

コンテンツに直接コピーできる、すぐに使用できる式について詳しくは、パーソナライゼーションのレシピ ​を参照してください。

クイックリファレンス quick-reference

この節には、このトピックに関連する解釈、検索、質問への回答をサポートすることを目的とした構造化された知識が含まれています。

完全に理解するには、この情報をこのページのドキュメント組み合わせる必要があります。 どちらのソースも単独で使用することを意図していません。このページでは、機能について説明していますが、この節では、用語、意図、適用可能性、制約の曖昧さを解消するのに役立つ追加コンテキストを提供しています。

概要

TL;DR

このページでは、Journey OptimizerのHandlebarsとPQL パーソナライゼーション構文について説明します。一般的なルール、予約済みキーワード、名前空間構造、文字システム、および一般的なランタイムエラーを回避するためのベストプラクティスです。

インテント

  • Handlebars ({{...}})とPQL ({%= ... %})の構文を使用するタイミングについて説明します
  • 一般的な構文ルールの適用:予約済み文字、大文字と小文字の区別、HTMLのエスケープ、バックスラッシュ処理
  • 予約キーワードと特殊属性キー(ハイフネーション付きの名前、数値イベント ID)を正しくエスケープする
  • 一致しない型の値を比較または渡す場合に型強制を適用する
  • 使用可能な名前空間からパーソナライゼーションを参照します:プロファイル、オーディエンス、オファー
  • 最も一般的なランタイムエラーと検証エラーを回避するには、ベストプラクティスに従ってください
用語集
  • Handlebars:属性のレンダリング、配列のループ、ブロックヘルパーの呼び出しに使用される{{...}} テンプレート構文。デフォルトでは、HTMLが出力をエスケープします。 (製品固有)
  • Profile Query Language (PQL):組み込み関数の呼び出し(例:upperCase()formatDate())と条件式の評価に使用される{%= ... %}式の構文。 (製品固有)
  • Triple-stash ({{{ }}}: HTML エスケープなしで値を出力するHandlebars構文バリアントです。値自体にエンコードすべきではないHTML文字が含まれている場合に便利です。
  • 予約済みキーワード: フィールド名または変数名として直接使用できないPQL ID (nextlastthis)は、スキーマフィールドでこれらの名前のいずれかを使用する場合、バックティックで折り返す必要があります。
  • 型強制:PQLの比較や算術の前に必要なstringToNumber()toBool()などの関数を使用して、あるデータ型から別のデータ型(文字列→数など)への値の明示的な変換。
  • 名前空間:パーソナライゼーションデータの最上位のグループ(プロファイル、オーディエンス、オファー)で、それぞれに独自のパス構造とアクセスルールがあります。
  • ブロックヘルパー: ヘルパー名の前に#によって識別されたHandlebars ヘルパーと、一致するクロージング /が、{{#each}}などのブロック構成に使用されます。
用語
  • 正規名: Handlebars — {{...}}構文、PQL — {%= ... %}構文
  • 混同しないでください: {{...}} (Handlebars – 変数とヘルパーをレンダリング、HTMLがエスケープ) ≠ {%= ... %} (PQL – 関数と式を評価) ≠ {%#if%} / {%/if%} (条件付きブロック構文、中括弧%)
  • 混同しないでください: {{profile.person.name}} (single-stash — HTML エスケープ出力) ≠ {{{profile.person.name}}} (triple-stash — エスケープされていない出力)
  • 予約済みキーワードのバックティック エスケープ({{...}}{%= ... %}の両方に適用)≠ハイフネーション付きキーバックティック エスケープ({%= ... %}個のPQL式でのみサポートされ、{{...}}ではサポートされていません)を混同しないでください。
  • 混同しないでください: = (PQLの等価演算子 – 正しい) ≠ == (無効なPQL – 構文エラーの原因)
ガードレールと制限
  • xEvent変数はパーソナライゼーション式では使用できません。xEventを参照すると、検証エラーが発生します。
  • {{...}} Handlebars ブロック内のPQL関数の呼び出しは失敗します。代わりに{%= ... %}を使用してください。
  • 条件付き構文{% if %} / {% elseif %} / {% endif %}はサポートされていません。{%#if%} / {%else if%} / {%/if%}を使用してください。
  • ハイフネーション付きフィールド名のバックティック エスケープは、PQL式({%= ... %})内でのみサポートされています。 {{...}} Handlebarsの補間では、バックティック構文は失敗しますが、ハイフネーションされたフィールド名は直接参照できます(例:{{profile.my-custom-field}})。
  • 予約済みキーワード (nextlastthis)は、スキーマフィールド名として使用する場合、バックティックで折り返す必要があります。{{...}}{%= ... %}の両方に適用されます。
  • 単一のバックスラッシュ \は、リテラル関数の引数としてサポートされていません。ダブルバックスラッシュ \\を使用してください。
  • PQLは強く型付けされています。比較または算術演算で一致しない型は、stringToNumber()toBool()、または同様の強制関数を使用して明示的に変換する必要があります。
FAQ

Q: {{...}}{%= ... %}?​を使用するタイミング

{{...}} (ハンドルバー)を使用して、属性値をレンダリングし、配列をループし、ブロックヘルパーを呼び出します。 {%= ... %} (PQL)を使用して、upperCase()formatDate()などの組み込み関数を呼び出し、条件式を評価します。

Q: HTML エンコーディングなしで値を出力するにはどうすればよいですか?

{{...}}の代わりにトリプルスタッシュ {{{ }}}を使用します。 シングルブレース Handlebars HTML-escapes出力(例:&&amp;になります)、トリプルスタッシュバイパスはエスケープします。

Q: PQLの正しい等価演算子は何ですか?

PQLの等価比較には、1つの=を使用します。 ==を使用すると、構文エラーが発生します。

Q:名前が予約されたキーワードであるスキーマフィールドを参照する方法(例:nextlastthis)を教えてください。

バックティックで折り返します:{{profile.person.\next&#39;.name}'。 これは、Handlebars パスとPQL エクスプレッションの両方に適用されます。

Q: {{...}} Handlebars ブロック内でPQL関数を呼び出すことはできますか?

いいえ。 {{...}}はHandlebars変数とヘルパーのみを解決します。 {{...}}内のPQL関数が「ヘルパーを見つけることができませんでした」エラーを引き起こします。 代わりに{%= functionName(...) %}を使用してください。

recommendation-more-help
journey-optimizer-help