Sur cette page : découvrez la syntaxe de personnalisation Handlebars et PQL dans Adobe Journey Optimizer, y compris les règles générales, les mots-clés réservés, la coercition de type, les espaces de noms disponibles et les bonnes pratiques.
Dans Journey Optimizer, la personnalisation utilise deux syntaxes complémentaires qui fonctionnent ensemble dans la même expression :
- Handlebars (
{{...}}) : utilisé pour effectuer le rendu des attributs de profil, passer en boucle sur des tableaux et appeler des assistants de blocs. Reportez-vous à la documentation HandlebarsJS pour obtenir une référence complète. - Profile Query Language (PQL) (
{%= ... %}) : utilisé pour appeler des fonctions intégrées (par exempleupperCase(),formatDate(),dateDiff()) et évaluer des expressions conditionnelles.
Il est essentiel de comprendre le contexte dans lequel vous vous trouvez pour éviter les erreurs d’exécution. Par exemple, un appel de fonction PQL placé dans {{...}} échouera, car Handlebars tente de le résoudre en tant qu’assistant plutôt que de l’évaluer en tant qu’expression PQL.
Exemples :
{{profile.person.name.firstName}}{%= upperCase(profile.person.name.firstName) %}{%#if profile.loyalty.tier = "gold"%}...{%/if%}{{#each profile.orders}}...{{/each}}La structure des attributs est définie dans un schéma XDM Adobe Experience Platform. En savoir plus.
Règles générales de syntaxe general-rules
-
Les identifiants peuvent être n’importe quel caractère Unicode, à l’exception des caractères spéciaux suivants, qui sont réservés à la syntaxe Handlebars :
code language-none Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~ -
La syntaxe est sensible à la casse.
-
Les mots true, false, null et undefined ne sont autorisés que dans la première partie d’une expression de chemin.
-
Dans Handlebars, les valeurs renvoyées par {{expression}} se caractérisent par un échappement HTML. Si l’expression contient
&, la sortie avec échappement HTML renvoyée est générée sous la forme&. Si vous ne souhaitez pas que Handlebars effectue l’échappement d’une valeur, utilisez trois accolades au lieu de deux.Supposons que la valeur du champ
profile.person.namesoit « Mark & Mary ». Le{{profile.person.name}}de syntaxe afficheMark & Mary, tandis que{{{profile.person.name}}}afficheMark & Mary. -
En ce qui concerne les arguments de fonctions littérales, l’analyseur de langage de création de modèles ne prend pas en charge la barre oblique inverse sans échappement (
\). Ce caractère doit avoir fait l’objet d’un échappement avec une barre oblique inverse supplémentaire (\). Exemple:{%= regexGroup("abc@xyz.com","@(\\w+)", 1)%} -
Pour inclure un guillemet double littéral dans une valeur de chaîne (par exemple lors de la génération d’une sortie JSON), insérez une barre oblique inverse (
\") dans l’échappement :code language-handlebars { "message": "Hello \"{{profile.person.name.firstName}}\"" }Sortie :
{ "message": "Hello \"John\"" }Vous pouvez également utiliser la triple accolade
{{{ }}}pour générer une valeur HTML sans échappement lorsque la valeur elle-même contient des caractères spéciaux que vous ne souhaitez pas encoder en HTML.
Mots-clés réservés reserved-keywords
Certains mots-clés sont réservés dans PQL (Profile Query Language) et ne peuvent pas être utilisés directement comme noms de champ ou de variable dans les expressions de personnalisation. Si votre schéma XDM contient des champs dont les noms correspondent à des mots-clés réservés, vous devez leur appliquer une séquence d’échappement à l’aide d’accents graves (`) pour les référencer dans vos expressions.
Les mots-clés réservés sont les suivants :
- Général :
let,export,to,as,this,last,next,now,NOW,today,yesterday,tomorrow,from,FROM,From,before,BEFORE,Before,after,AFTER,After, - Unités de temps :
millisecond,milliseconds,second,seconds,minute,minutes,hour,hours,day,days,week,weeks,month,months,year,years,decade,decades,century,centuries,millennium,millennia, - Opérateurs booléens et logiques :
true,TRUE,True,false,FALSE,False,not,NOT,Not,and,AND,And,or,OR,Or,null,NULL,Null,
Exemple:
Si votre schéma de profil comporte un champ nommé next, vous devez l’encadrer de guillemets inversés :
{{profile.person.`next`.name}}
Sans les guillemets inversés, l’éditeur de personnalisation échouera lors de la validation et vous obtiendrez une erreur.
{{...}} et aux expressions PQL {%= ... %}, car ces mots-clés sont réservés au niveau de la résolution du chemin. Cette approche est différente des noms de champ avec trait d’union, où l’échappement avec apostrophe inverse n’est pris en charge que dans les expressions PQL. Voir la section Clés d’attribut avec trait d’union.Règles de syntaxe PQL pour les clés d’attribut spéciales pql-special-keys
En plus des mots-clés réservés, deux cas supplémentaires nécessitent une séquence d’échappement avec apostrophe inverse dans les expressions PQL.
Clés d’attribut avec trait d’union hyphenated-keys
Si votre schéma XDM contient des noms de champ avec des tirets (par exemple my-field, event-type) ou des noms commençant par des chiffres ou en contenant, placez la clé entre apostrophes inverses dans les expressions PQL :
{%= profile.events.`order-total` > 100 %}
{%= ... %}). Il n’est pas pris en charge dans l’interpolation Handlebars ({{...}}). Toutefois, les noms de champ avec tiret peuvent être référencés directement dans les blocs {{...}} (par exemple {{profile.my-custom-field}}). Seule la syntaxe des apostrophes inverses ne fonctionne pas dans ce cas.Sans apostrophes inverses dans une expression PQL, le trait d’union est interprété comme un opérateur de soustraction et provoque une erreur de syntaxe PQL.
Identifiants d’événements numériques dans les attributs de contexte numeric-event-ids
Lors du référencement d’attributs d’événements de contexte où l’identifiant d’événement est un nombre (par exemple, 1697323153), placez-le entre apostrophes inverses. Cela s’applique également aux fonctions internes telles que formatDate() :
Coercition de type type-coercion
PQL a un type fort. Lors de la comparaison ou de la transmission de valeurs, les deux côtés doivent être du même type. Cas courants :
stringToNumber() avant l’arithmétique ou la comparaison : {%= stringToNumber(profile.loyalty.pointsBalance) > 500 %}string_to_integer() ou stringToNumber() avant l’arithmétiquetoBool() pour la conversion : {%= toBool(profile.consents.email.val) = true %}Espaces de noms disponibles namespaces
-
Profile
Cet espace de noms vous permet de référencer tous les attributs définis dans le schéma de profil décrit dans la documentation Modèle de données Adobe Experience Platform (XDM).
Les attributs doivent être définis dans le schéma avant d’être référencés dans un bloc de personnalisation Journey Optimizer.
Pour plus d’informations sur l’utilisation des attributs de profil dans des conditions, consultez cette section.
accordion Exemples de références {{profile.person.name.fullName}}{{profile.person.name.firstName}}{{profile.person.gender}}{{profile.personalEmail.address}}{{profile.mobilePhone.number}}{{profile.homeAddress.city}}{{profile.faxPhone.number}}
-
Audience
Pour en savoir plus sur le service de segmentation, consultez cette documentation.
-
Offres
Cet espace de noms vous permet de référencer les décisions d’offre existantes.
Pour référencer une offre, vous devez déclarer un chemin avec les différentes informations qui définissent une offre. Ce chemin possède la structure suivante :
offers.Type.[Placement Id].[Activity Id].Attributeoù :
offersidentifie l’expression de chemin appartenant à l’espace de noms de l’offre.Typedétermine le type de représentation de l’offre. Les valeurs possibles sont les suivantes :image,htmlettext.Placement IdetActivity Idsont des identifiants d’emplacement et d’activité.Attributessont des attributs spécifiques à l’offre qui dépendent du type d’offre. Exemple :deliveryUrlpour les images
Pour plus d’informations sur l’API Decisions et sur la représentation des offres, consultez cette page.
Toutes les références sont validées par rapport au schéma d’offres avec un mécanisme de validation décrit sur cette page.
accordion Exemples de références -
Emplacement où l’image est hébergée :
offers.image.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].deliveryUrl -
URL de la cible lorsque vous cliquez sur l’image :
offers.image.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].linkUrl -
Contenu textuel de l’offre provenant du moteur de décision :
offers.text.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].content -
Contenu HTML de l’offre provenant du moteur de décision :
offers.html.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].content
Assistants helpers-all
Un assistant Handlebars est un identifiant simple qui peut être suivi de paramètres. Chaque paramètre est une expression Handlebars. Ces assistants sont accessibles depuis n’importe quel contexte dans un modèle.
Ces assistants de bloc sont identifiés par un # placé devant le nom de l’assistant et une / correspondante doit être placée à la fin avec le même nom.
Les blocs sont des expressions qui ont une ouverture ({{# }}) et une fermeture ({{/}}) de bloc.
Pour plus d’informations sur les fonctions d’assistant, consultez cette section.
Types littéraux literal-types
Adobe Journey Optimizer prend en charge les types littéraux suivants :
Exemples :
"prospect", "jobs", "articles"Exemples :
-201, 0, 412Remarque : vous ne pouvez pas accéder directement aux propriétés des éléments dans un tableau.
Exemples :
[1, 4, 7], ["US", "FR"]Bonnes pratiques best-practices
Consultez ces règles de syntaxe avant de créer des expressions de personnalisation. La plupart des erreurs d’exécution proviennent du mélange des contextes Handlebars et PQL.
Utilisez la syntaxe correcte du bloc conditionnel
Utilisez toujours {%#if%} / {%else if%} / {%else%} / {%/if%}. La syntaxe {% if %} / {% elseif %} / {% endif %} n’est pas prise en charge.
N’appelez pas les fonctions PQL dans les blocs Handlebars {{...}}.
{{...}} résout uniquement les variables Handlebars et les assistants. Il n’évalue pas les éléments PQL. Encapsuler une fonction PQL comme upperCase() dans {{...}} provoque une erreur du type « Assistant introuvable ». Utilisez plutôt {%= ... %} :
{{upperCase(cleanName)}}{%= upperCase(cleanName) %}Utiliser un alias de boucle nommé lors de la combinaison de {{#each}} avec{%#if%}
this.field est résolu par le moteur de rendu Handlebars, mais pas par l’évaluateur PQL dans une condition {%#if%}. Définissez un alias nommé avec as |item| afin que les deux contextes puissent résoudre le champ :
Attribuer des résultats de fonction PQL à une variable avant la boucle
Les champs PQL définis par l’utilisateur ou l’utilisatrice, tels que topN ne peuvent pas être appelés directement dans {{#each}}. Évaluez-les d’abord avec {% let %}, puis effectuez une itération sur le résultat :
Utilisez {% let %} pour éviter de répéter les appels de fonction
Lorsqu’une valeur calculée doit être utilisée plusieurs fois, stockez-la dans une variable. Cela améliore la lisibilité et évite les évaluations redondantes :
Utiliser l’ordre correct des arguments pourdateDiff
dateDiff(start, end) prend la date antérieure en premier. Pour calculer le nombre de jours restants jusqu’à une date ultérieure, transmettez la date actuelle en premier argument :
Utilisez = et non== pour les comparaisons d’égalité dans PQL.
PQL utilise un seul opérateur = pour l’égalité. L’utilisation de == résultats entraîne une erreur de syntaxe.
Utiliser des apostrophes inverses pour les noms de champ avec trait d’union, dans les expressions PQL uniquement
Si un nom de champ de schéma XDM contient un trait d’union (par exemple, order-total), placez-le entre des apostrophes inverses pour éviter qu’il soit analysé en tant qu’opérateur de soustraction. Il n’est pris en charge que dans les expressions PQL {%= ... %}, et non dans les blocs Handlebars {{...}} :
{%= profile.events.`order-total` > 100 %}
Pour les expressions prêtes à l’emploi que vous pouvez copier directement dans votre contenu, consultez la section Recettes de personnalisation.
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()ortoBool(), 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
xEventvariable is not available in personalization expressions; any reference toxEventresults 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 likeupperCase()andformatDate(), 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&); 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.