Sintassi di personalizzazione personalization-syntax

In questa pagina: Scopri la sintassi di personalizzazione Handlebars e PQL in Adobe Journey Optimizer, incluse le regole generali, le parole chiave riservate, la coercizione del tipo, gli spazi dei nomi disponibili e le best practice.

Personalization in Journey Optimizer utilizza due sintassi complementari che funzionano insieme nella stessa espressione:

  • Handlebars ({{...}}): utilizzato per eseguire il rendering degli attributi di profilo, eseguire il loop su array e chiamare gli helper di blocco. Consulta la documentazione HandlebarsJS per un riferimento completo.
  • Profile Query Language (PQL) ({%= ... %}): utilizzato per chiamare funzioni incorporate (ad esempio upperCase(), formatDate(), dateDiff()) e valutare espressioni condizionali.

Per evitare errori di runtime, è fondamentale capire in quale contesto ci si trova. Ad esempio, una chiamata di funzione PQL inserita all’interno di {{...}} avrà esito negativo perché Handlebars tenta di risolverla come helper anziché valutarla come espressione di PQL.

Esempi:

Caso d’uso
Sintassi
Eseguire il rendering di un attributo di profilo
{{profile.person.name.firstName}}
Chiamare una funzione PQL
{%= upperCase(profile.person.name.firstName) %}
Blocco condizionale
{%#if profile.loyalty.tier = "gold"%}...{%/if%}
Eseguire il ciclo su un array
{{#each profile.orders}}...{{/each}}

La struttura degli attributi è definita in uno schema XDM di Adobe Experience Platform. Ulteriori informazioni.

TIP
Per le espressioni pronte all'uso che applicano queste sintassi a scenari reali, ad esempio formattazione delle date, conteggi, fallback condizionali e altro ancora, vedere la pagina Composizioni di Personalization.

Regole generali di sintassi general-rules

  • Gli identificatori possono essere qualsiasi carattere Unicode ad eccezione dei seguenti caratteri speciali, che sono riservati per la sintassi Handlebars:

    code language-none
    Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~
    
  • La sintassi fa distinzione tra maiuscole e minuscole.

  • Le parole true, false, null e undefined sono consentite solo nella prima parte di un’espressione di percorso.

  • In Handlebars, i valori restituiti da {{expression}} sono con escape HTML. Se l’espressione contiene &, l’output con escape HTML restituito verrà generato come &amp;. Se non vuoi che Handlebars sfugga a un valore, utilizza il “triplo-stash”.

    Si supponga che il valore del campo profile.person.name sia “Mark & Mary”. La sintassi {{profile.person.name}} visualizzerà Mark &amp; Mary, mentre {{{profile.person.name}}} visualizzerà Mark & Mary.

  • Per quanto riguarda gli argomenti delle funzioni letterali, il parser del linguaggio del modello non supporta una singola barra rovesciata senza escape (\). Questo carattere deve essere preceduto da una barra rovesciata (\). Esempio:

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

  • Per includere virgolette doppie letterali in un valore stringa (ad esempio, durante la generazione dell’output JSON), esegui l’escape con una barra rovesciata (\"):

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

    Output: { "message": "Hello \"John\"" }

    In alternativa, utilizza il triplo-stash {{{ }}} per generare HTML senza escape quando il valore stesso contiene caratteri speciali che non desideri siano codificati in HTML.

Parole chiave riservate reserved-keywords

Alcune parole chiave sono riservate in Profile Query Language (PQL) e non possono essere utilizzate direttamente come nomi di campi o variabili nelle espressioni di personalizzazione. Se lo schema XDM contiene campi con nomi che corrispondono a parole chiave riservate, è necessario eseguirne l’escape utilizzando apici inversi (`) per farvi riferimento nelle espressioni.

Le parole chiave riservate includono:

  • Generale: let, export, to, as, this, last, next, now, NOW, today, yesterday, tomorrow, from, FROM, From, before, BEFORE, Before, after, AFTER, After
  • Unità di tempo: millisecond, milliseconds, second, seconds, minute, minutes, hour, hours, day, days, week, weeks, month, months, year, years, decade, decades, century, centuries, millennium, millennia
  • Operatori booleani e logici: true, TRUE, True, false, FALSE, False, not, NOT, Not, and, AND, And, or, OR, Or, null, NULL, Null

Esempio:

Se lo schema del profilo dispone di un campo denominato next, è necessario racchiuderlo in apici:

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

Se non vengono utilizzati i backtick, l’editor di personalizzazione non riuscirà a eseguire la convalida e restituirà un errore.

NOTE
L'escape backtick per le parole chiave riservate si applica sia ai percorsi Handlebars {{...}} che alle espressioni PQL {%= ... %}, poiché queste parole chiave sono riservate al livello di risoluzione del percorso. Questa funzione è diversa dai nomi di campo sillabati, in cui l’escape con apice inverso è supportato solo all’interno di espressioni PQL. Vedi Chiavi attributo con sillabazione.

Regole di sintassi PQL per chiavi di attributi speciali pql-special-keys

Oltre alle parole chiave riservate, due casi aggiuntivi richiedono l’escape backtick nelle espressioni PQL.

Chiavi attributo sillabate hyphenated-keys

Se lo schema XDM contiene nomi di campo con trattini (ad esempio my-field, event-type) o nomi che iniziano con o contengono numeri, racchiudi la chiave tra i segni di sospensione all’interno delle espressioni PQL:

{%= profile.events.`order-total` > 100 %}
NOTE
L'escape di tipo Backtick è supportato solo all'interno di espressioni PQL ({%= ... %}). Non è supportato nell'interpolazione Handlebars ({{...}}). Tuttavia, è possibile fare riferimento direttamente ai nomi dei campi sillabati nei blocchi {{...}} (ad esempio {{profile.my-custom-field}}); solo la sintassi backtick non riesce.

Senza apici retroversi in un’espressione PQL, il trattino viene interpretato come un operatore di sottrazione e causa un errore di sintassi PQL.

ID evento numerici negli attributi di contesto numeric-event-ids

Quando si fa riferimento agli attributi dell’evento di contesto in cui l’ID evento è un numero (ad esempio 1697323153), racchiuderlo in apici. Questo vale anche all’interno di funzioni come formatDate():

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

Tipo coercizione type-coercion

PQL è fortemente tipizzato. Quando si confrontano o si trasmettono valori, entrambi i lati devono essere dello stesso tipo. Casi comuni:

Scenario
Soluzione
Valore numerico memorizzato come stringa
Usa stringToNumber() prima di aritmetica o confronto: {%= stringToNumber(profile.loyalty.pointsBalance) > 500 %}
Intero memorizzato come stringa
Usa string_to_integer() o stringToNumber() prima dell’aritmetica
Booleano memorizzato come stringa
Usa toBool() per convertire: {%= toBool(profile.consents.email.val) = true %}

Spazi dei nomi disponibili namespaces

  • Profilo

    Questo spazio dei nomi consente di fare riferimento a tutti gli attributi definiti nello schema del profilo descritto nella documentazione di Adobe Experience Platform Data Model (XDM).

    Gli attributi devono essere definiti nello schema prima di essere referenziati in un blocco di personalizzazione Journey Optimizer.

    Per ulteriori informazioni su come sfruttare gli attributi del profilo nelle condizioni, consulta questa sezione.

    accordion
    Riferimenti di esempio
    • {{profile.person.name.fullName}}
    • {{profile.person.name.firstName}}
    • {{profile.person.gender}}
    • {{profile.personalEmail.address}}
    • {{profile.mobilePhone.number}}
    • {{profile.homeAddress.city}}
    • {{profile.faxPhone.number}}
  • Pubblico

    Per ulteriori informazioni sul servizio di segmentazione, consulta questa documentazione.

  • Offerte

    Questo spazio dei nomi consente di fare riferimento alle decisioni sulle offerte esistenti.

    Per fare riferimento a un’offerta è necessario dichiarare un percorso con le diverse informazioni che definiscono un’offerta. Questo percorso ha la seguente struttura:

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

    dove:

    • offers identifica l’espressione di percorso appartenente allo spazio dei nomi dell’offerta
    • Type determina il tipo di rappresentazione dell’offerta. I valori possibili sono: image, html e text
    • Placement Id e Activity Id sono identificatori di posizionamento e attività
    • Attributes sono attributi specifici dell’offerta che dipendono dal tipo di offerta. Esempio: deliveryUrl per le immagini

    Per ulteriori informazioni sull’API Decisions e sulle rappresentazioni di offerte, consulta questa pagina

    Tutti i riferimenti vengono convalidati in base allo schema delle offerte con un meccanismo di convalida descritto in questa pagina

    accordion
    Riferimenti di esempio
    • Posizione in cui è ospitata l’immagine:

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

    • URL di destinazione quando fai clic sull’immagine:

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

    • Contenuto del testo dell’offerta proveniente dal motore decisionale:

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

    • Contenuto HTML dell’offerta proveniente dal motore decisionale:

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

Helper helpers-all

Un helper Handlebars è un semplice identificatore che può essere seguito da parametri. Ogni parametro è un’espressione Handlebars. È possibile accedere a questi helper da qualsiasi contesto in un modello.

Questi helper di blocco sono identificati da un # che precede il nome dell’helper e richiedono un / di chiusura corrispondente, con lo stesso nome.

I blocchi sono espressioni con un blocco di apertura ({{# }}) e chiusura ({{/}}).

Per ulteriori informazioni sulle funzioni di supporto, consultare questa sezione.

Tipi letterali literal-types

Adobe Journey Optimizer supporta i seguenti tipi letterali:

Letterale
Definizione
Stringa
Tipo di dati costituito da caratteri racchiusi tra virgolette doppie.
Esempi: "prospect", "jobs", "articles"
Booleano
Tipo di dati true o false.
Intero
Tipo di dati che rappresenta un numero intero. Può essere positivo, negativo o zero.
Esempi: -201, 0, 412
Array
Tipo di dati composto da un gruppo di altri valori letterali. Utilizza parentesi quadre per raggruppare e virgole per delimitare tra valori diversi.
Nota: non è possibile accedere direttamente alle proprietà degli elementi all’interno di un array.
Esempi: [1, 4, 7], ["US", "FR"]
CAUTION
L'utilizzo della variabile xEvent non è disponibile nelle espressioni di personalizzazione. Qualsiasi riferimento a xEvent provocherà errori di convalida.

Best practice best-practices

Rivedi queste regole di sintassi prima di creare espressioni di personalizzazione. La maggior parte degli errori di runtime deriva dalla combinazione di Handlebars e contesti di PQL.

Utilizzare la sintassi del blocco condizionale corretta

Usa sempre {%#if%} / {%else if%} / {%else%} / {%/if%}. Sintassi {% if %} / {% elseif %} / {% endif %} non supportata.

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

Non chiamare funzioni PQL all’interno di {{...}} blocchi Handlebars

{{...}} risolve solo le variabili Handlebars e gli helper, ma non valuta PQL. Il wrapping di una funzione PQL come upperCase() in {{...}} causa un errore di tipo “Impossibile trovare l’helper”. Utilizza invece {%= ... %}:

Non corretto
Corretto
{{upperCase(cleanName)}}
{%= upperCase(cleanName) %}

Utilizzare un alias loop denominato quando si combina {{#each}} con{%#if%}

this.field è risolto dal renderer Handlebars ma non dal valutatore PQL all’interno di una condizione {%#if%}. Definire un alias denominato con as |item| in modo che entrambi i contesti possano risolvere il campo:

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

Assegnare i risultati della funzione PQL a una variabile prima di eseguire un ciclo

Impossibile chiamare le FDU di PQL come topN direttamente in {{#each}}. Valutali prima con {% let %}, quindi esegui un’iterazione sul risultato:

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

Utilizza {% let %} per evitare di ripetere le chiamate di funzione

Se un valore calcolato è necessario più di una volta, memorizzalo in una variabile. Ciò migliora la leggibilità e impedisce le valutazioni ridondanti:

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

Utilizza l’ordine corretto degli argomenti perdateDiff

dateDiff(start, end) prende prima la data precedente. Per calcolare i giorni rimanenti fino a una data futura, passare la data corrente come primo argomento:

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

Utilizzare = per i confronti di uguaglianza in PQL, non==

PQL utilizza un singolo operatore = per l’uguaglianza. L’utilizzo di == genera un errore di sintassi.

Usa i contrassegni per i nomi dei campi sillabati, solo nelle espressioni PQL

Se il nome di un campo dello schema XDM contiene un trattino (ad esempio order-total), racchiudilo tra apici per evitare che il trattino venga analizzato come operatore di sottrazione. Questo è supportato solo all’interno di {%= ... %} espressioni PQL, non nei blocchi Handlebars {{...}}:

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

Per le espressioni pronte all’uso che puoi copiare direttamente nel contenuto, consulta Composizioni di Personalization.

AI Knowledge Reference

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 the Handlebars and PQL personalization syntaxes in Journey Optimizer — their general rules, reserved keywords, namespace structure, type system, and best practices for avoiding common runtime errors.

Intents:

  • Understand when to use Handlebars ({{...}}) vs. PQL ({%= ... %}) syntax
  • Apply general syntax rules: reserved characters, case sensitivity, HTML escaping, backslash handling
  • Escape reserved keywords and special attribute keys (hyphenated names, numeric event IDs) correctly
  • Apply type coercion when comparing or passing values of mismatched types
  • Reference personalization from the available namespaces: Profile, Audience, Offers
  • Follow best practices to avoid the most common runtime and validation errors

Glossary:

  • Handlebars: The {{...}} templating syntax used for rendering attributes, looping over arrays, and calling block helpers; HTML-escapes output by default. (product-specific)
  • Profile Query Language (PQL): The {%= ... %} expression syntax used for calling built-in functions (e.g. upperCase(), formatDate()) and evaluating conditional expressions. (product-specific)
  • Triple-stash ({{{ }}}): A Handlebars syntax variant that outputs values without HTML escaping, useful when the value itself contains HTML characters that should not be encoded.
  • Reserved keywords: PQL identifiers that cannot be used directly as field or variable names, grouped as general keywords (let, export, to, as, this, last, next, now, NOW, today, yesterday, tomorrow, from, FROM, From, before, BEFORE, Before, after, AFTER, After), time units (millisecond, milliseconds, second, seconds, minute, minutes, hour, hours, day, days, week, weeks, month, months, year, years, decade, decades, century, centuries, millennium, millennia), and boolean/logical operators (true, TRUE, True, false, FALSE, False, not, NOT, Not, and, AND, And, or, OR, Or, null, NULL, Null); must be wrapped in backticks when a schema field uses one of these names.
  • Type coercion: The explicit conversion of a value from one data type to another (e.g. string → number) using functions like stringToNumber() or toBool(), required before comparison or arithmetic in PQL.
  • Namespace: The top-level grouping of personalization data — Profile, Audience, Offers — each with its own path structure and access rules.
  • Block helper: A Handlebars helper identified by # before the helper name and a matching closing /, used for block constructs like {{#each}}.

Guardrails:

  • The xEvent variable is not available in personalization expressions; any reference to xEvent results in validation failures.
  • PQL function calls inside {{...}} Handlebars blocks will fail; use {%= ... %} instead.
  • The {% if %} / {% elseif %} / {% endif %} conditional syntax is not supported; use {%#if%} / {%else if%} / {%/if%}.
  • Backtick escaping for hyphenated field names is only supported inside PQL expressions ({%= ... %}). In {{...}} Handlebars interpolation, backtick syntax fails — but hyphenated field names can still be referenced directly (e.g. {{profile.my-custom-field}}).
  • Reserved keywords (general, time-unit, and boolean/logical, e.g. next, last, this, day, year, true, and, or) must be wrapped in backticks when used as schema field names; applies to both {{...}} and {%= ... %}.
  • Single backslash \ is not supported as a literal function argument; use double backslash \\.
  • PQL is strongly typed; mismatched types in comparisons or arithmetic require explicit conversion using stringToNumber(), toBool(), or similar coercion functions.

Terminology:

  • Canonical name: Handlebars — for the {{...}} syntax; PQL — for the {%= ... %} syntax
  • Do not confuse: {{...}} (Handlebars — renders variables and helpers, HTML-escaped) ≠ {%= ... %} (PQL — evaluates functions and expressions) ≠ {%#if%} / {%/if%} (conditional block syntax, percent-curly braces)
  • Do not confuse: {{profile.person.name}} (single-stash — HTML-escaped output) ≠ {{{profile.person.name}}} (triple-stash — unescaped output)
  • Do not confuse: reserved keyword backtick escaping (applies to both {{...}} and {%= ... %}) ≠ hyphenated key backtick escaping (only supported inside {%= ... %} PQL expressions, not in {{...}})
  • Do not confuse: = (PQL equality operator — correct) ≠ == (not valid PQL — causes a syntax error)

FAQ:

  • Q: When should I use {{...}} vs. {%= ... %}? — Use {{...}} (Handlebars) to render attribute values, loop over arrays, and call block helpers. Use {%= ... %} (PQL) to call built-in functions like upperCase() and formatDate(), and to evaluate conditional expressions.
  • Q: How do I output a value without HTML encoding? — Use the triple-stash {{{ }}} instead of {{...}}. Single-brace Handlebars HTML-escapes output (e.g., & becomes &amp;); triple-stash bypasses escaping.
  • Q: What is the correct equality operator in PQL? — Use a single = for equality comparisons in PQL. Using == is a syntax error.
  • Q: How do I reference a schema field whose name is a reserved keyword (e.g. next, last, this)? — Wrap it in backticks: {{profile.person.\next`.name}}`. This applies to both Handlebars paths and PQL expressions.
  • Q: Can I call PQL functions inside {{...}} Handlebars blocks? — No. {{...}} resolves Handlebars variables and helpers only. A PQL function inside {{...}} causes a “could not find helper” error. Use {%= functionName(...) %} instead.
recommendation-more-help
journey-optimizer-help