Personyze-acties — banners, pop-ups, aanbevelingswidgets, e-mails en meer — worden normaal gesproken visueel ontworpen in de campagne-editor. Maar achter elke visuele editor zit HTML-broncode met de templatedirectives van Personyze, en die HTML kun je direct bewerken als je meer controle nodig hebt. Dit artikel is de volledige naslag van de templatetaal.
De taal is gewone HTML en CSS, met een paar toevoegingen:
- Preprocessing-directives tussen
${...}— variabelen, voorwaarden, lussen en functies die aan de serverkant worden geëvalueerd voordat de HTML naar de pagina gaat. - Speciale classnamen (met het voorvoegsel
$) die van gewone elementen widgets maken die Personyze herkent — knoppen, pop-ups, wisselbare gebieden, voorwaardelijke formulieren en meer. - Menudirectives onderaan de template die bepalen welke instellingen iemand zonder ontwikkelkennis in de visuele editor van de interface ziet.
Preprocessing-directives
Een dollarteken gevolgd door accolades markeert een preprocessing-directive. De inhoud tussen de accolades wordt geëvalueerd en door het resultaat vervangen voordat de HTML naar de browser gaat. Tussen de accolades kun je een variabele gebruiken, een functieaanroep op een variabele, of een van de structurele directives die hieronder worden behandeld.
${some_variable}
De directive kan tekst opleveren die zelf weer een directive bevat — Personyze evalueert in twee rondes:
- Preprocess-ronde — vult
${args->...}-argumentvariabelen in de template in. - Gebruikersronde — vult variabelen per gebruiker in (
${first_name},${country_code}, enz.) voor elke afzonderlijke bezoeker.
Preprocess-variabelen (args)
Om een preprocess-variabele te maken — het soort dat als bewerkbaar veld in de visuele interface verschijnt — declareer je die één keer onderaan de template met een ${menu} -directive, en verwijs je er overal in de body van de template naar met ${args->name}:
<p title="${args->main_text:html}">
${args->main_text}
</p>
${menu args->main_text name=\'Main text\'}
Nu toont de interface een bewerkbaar veld “Main text”. Wat de gebruiker daar typt, wordt ingevoegd zowel in de <p> -tag als in het title -attribuut ervan (met speciale HTML-tekens geëscapet via de :html -conversie, zodat de waarde niet uit het attribuut kan breken en extra tags kan injecteren).
Syntaxis van argumentexpressies
De algemene vorm is het sleutelwoord args , een pijl, de naam van de variabele, en daarna nul of meer conversies met een dubbele punt ervoor:
${args->variable_name:function1:function2(parameter)}
Variabelen uit het gebruikersprofiel
De tweede verwerkingsronde vult waarden per gebruiker in. Personyze heeft deze ingebouwde profielvariabelen:
first_namelast_nameemailindustry
Je kunt ook eigen profielvelden definiëren en er waarden voor verzamelen via formulieren of de API. Eenmaal gedefinieerd zijn ze op dezelfde manier beschikbaar:
${first_name:default('User')}
Preprocess-variabelen kunnen tekst opleveren die gebruikersvariabelen voor de tweede ronde bevat. Gebruik verdubbelde apostrofs voor geneste standaardwaarden:
<p>
${args->main_text:default(\'Dear, ${first_name:default(\'\'User\'\')}\')}
</p>
${menu args->main_text name=\'Main text\'}
Sessie- en paginavariabelen
Variabelen die afhangen van de huidige surfsessie en het apparaat van de bezoeker:
| Variabele | Geeft terug |
|---|---|
url_host_port |
Domeinnaam van de site. |
url_path |
URL-pad (het deel na de domeinnaam). |
ur |
De volledige URL van de huidige pagina. |
country_code |
Landcode van twee letters (bijv. US, DE). |
city |
Plaatsnaam. |
lang_0 |
Primaire browsertaal. |
known_device_type |
regular (desktop), tablet, of phone. |
is_returning_user |
0 voor nieuwe gebruikers, 1 voor terugkerende. |
landing_url |
URL van de landingspagina waarmee deze sessie begon. |
landing_host_port |
Domeindeel van de landingspagina. |
landing_path |
URL-paddeel van de landingspagina. |
part_of_day() |
morning, afternoon, evening, of night. |
weekday |
Dag van de week als getal: 0 = zondag, 1 = maandag, …, 6 = zaterdag. |
day |
Dag van de maand. |
last_month_day |
Laatste dag van de huidige maand — 28, 29, 30 of 31. |
Functies
Functies pas je toe op variabelen met een dubbele punt ervoor:
${variable:func_name}
${variable:func_name(parameter)}
${variable:func_name(\'parameter\')}
${variable:func_name(\'param1\', \'param2\', \'param3\')}
Bevat een parameter komma’s, apostrofs of sluithaakjes — of is er meer dan één parameter — dan moet die tussen aanhalingstekens. Om een apostrof in een tekenreeks tussen aanhalingstekens weer te geven, verdubbel je die: :func_name('I''m a string').
Tekenreeksen & HTML
| Functie | Beschrijving |
|---|---|
html |
Speciale HTML-tekens escapen: &→&, "→", <→<. Gebruik dit altijd bij waarden die in attributen worden ingevoegd, of overal waar door gebruikers aangeleverde content niet als markup mag worden verwerkt. |
default |
Voor args -variabelen: geef de huidige/beginwaarde op. Voor variabelen uit het gebruikersprofiel: geef een fallback op voor als de variabele leeg is. Bij argszet je het maar op één plek, ook als de variabele meerdere keren voorkomt. |
json |
Zet de waarde om naar een JSON-string. Handig om willekeurige data veilig in JavaScript op te nemen: onclick="alert(${p->title:json:html})". |
url |
URL-coderen (bijv. ? → %3F). |
lc |
Kleine letters: ${p->title:lc}. |
uc |
Hoofdletters. |
replace |
Vervang alle voorkomens van een deeltekenreeks door een andere: ${url:replace('http://', 'https://')}. |
regexp_replace |
Vervangen via een reguliere expressie. |
ellipsis |
Inkorten tot de eerste N tekens en … toevoegen als er iets is weggesneden: ${p->description_long:ellipsis(50)}. |
left |
De eerste N tekens (zonder beletselteken). |
right |
De laatste N tekens. |
substr |
Vanaf teken N, M tekens eruit halen. |
substring |
Deeltekenreeks van teken N tot teken M (exclusief). |
text_after |
Tekst na een opgegeven woord of deeltekenreeks. |
text_before |
Tekst vóór een opgegeven woord of deeltekenreeks. |
Getallen & prijzen opmaken
| Functie | Beschrijving |
|---|---|
sprintf |
Een getal opmaken met placeholders. %s voor ruw, %f als getal, of %[#,###.##]f voor volledige controle over duizendtallen/decimalen. # is een optioneel cijfer, 0 is verplicht. Gebruik g in plaats van f om nullen achter de komma weg te laten bij hele getallen. Arabische cijfers via ٠ als placeholder. |
price |
Opmaken als prijs met de getalnotatie van je account. Twee vooraf ingestelde notaties: :price voor de standaard, :price('alternative') voor de tweede. De interface biedt een instelling voor allebei. |
round |
Afronden op het dichtstbijzijnde getal. |
floor |
Afronden richting min oneindig. |
ceil |
Afronden richting plus oneindig. |
truncate |
Het deel achter de komma weglaten. |
Personyze-tabellen doorlopen (${foreach})
Personyze-tabellen — je productcatalogus, artikelcatalogus, berekende gebruikersinteresses — doorloop je met ${foreach ... as alias where ... limit N} ... ${end}:
${foreach products as p where p->price_after_discount < p->price_before_discount limit 5}
<div>
${p->title}
</div>
${end}
Aanbevelingswidgets gebruiken dit patroon om de echte product-/contentkaarten weer te geven. Het aanbevelingsalgoritme dat in de interface is gekozen, bepaalt de tabelnaam en de filters die in de template verschijnen. Voorbeeld voor “bestsellers in de recente periode”:
${foreach sum_products as p where p->for_period=\'recently\' and p->n_goal>0 order by p->n_goal desc limit 12}
...
${end}
Je kunt meerdere ${foreach} -lussen in een template hebben, ook geneste. Heeft een ervan de alias main, dan bestuurt de kiezer voor het aanbevelingsalgoritme in de interface die lus. Anders bestuurt die de eerste die wordt gevonden.
Product dat nu wordt bekeken
Wordt er op de huidige pagina een productweergave-event gemeld, dan kun je de details van het product dat nu wordt bekeken direct opvragen via viewing_product — er is geen ${foreach} nodig:
You're interested in ${viewing_product->color} color.
Andere automatisch beschikbare tabellen met één rij:
viewing_product— het product dat nu wordt bekeken (als er op deze pagina een weergave-event is gemeld).last_viewed_product— het laatst bekeken product in de sessie van de bezoeker.last_extra_product— het product dat het laatst aan de winkelwagen is toegevoegd.
Voorwaardelijke directives
${if} / ${else if} / ${else}
Neem delen van de template op op basis van een preprocess-variabele, een profielvariabele of een tabelkolom:
${foreach products as p where p->price_after_discount < p->price_before_discount limit 5}
<div>
${p->title}
</div>
<div>
${if p->price_after_discount < p->price_before_discount}
${p->price_after_discount}
<strike>${p->price_before_discount}</strike>
${else if p->price_after_discount < 10}
Cheaper than $10.
${else}
${p->price_after_discount}
${end}
</div>
${end}
Voorwaardelijke expressies kunnen naar args verwijzen, zodat gebruikers filters kunnen bedienen:
${foreach products as p limit 5}
${if p->price_after_discount > args->min_price}
<div>${p->title}</div>
${end}
${end}
${menu args->min_price name=\'Show products not cheaper than\', type=\'number\'}
${case}
Twee vormen — booleaans (elke when is een eigen voorwaarde) en expressie (elke when wordt vergeleken met de case-expressie):
${case}
${when known_device_type = \'phone\'}
On phone
${when known_device_type = \'regular\'}
On desktop
${else}
Not known
${end}
${case known_device_type}
${when \'phone\'}
On phone
${when \'regular\'}
On desktop
${else}
Not known
${end}
Voorwaardelijke blokken (aan/uit te zetten in de interface)
Voorwaardelijke blokken zijn HTML-elementen die zijn gemarkeerd met ${block->block_name}. De interface toont een schakelaar die het blok aan- of uitzet — handig voor opties als “met knop / zonder knop”.
${block->with_button:default(0)}
<div>
<button type="button">See more</button>
</div>
${menu block->with_button name=\'With button\'}
HTML-structuur & by_id
Templates kunnen elke HTML bevatten — ook <style> -tags. Er worden een paar transformaties toegepast:
id -attributen worden verwijderd — maar zijn bereikbaar via by_id
Heeft je template elementen met id -attributen, dan worden die attributen vóór het weergeven verwijderd (om botsingen met andere markup op de pagina te voorkomen). Maar je kunt die elementen nog steeds aanspreken via een speciaal by_id -object dat beschikbaar is in onclick -handlers en een speciaal ontplready -attribuut:
<div style="background-color:transparent; display:flex; align-items:center; gap:0.3em">
<img id="main_icon" src="https://www.google.com/favicon.ico">
<button type="button" onclick="by_id.display.textContent = by_id.main_icon.width">Get icon width</button>
<div id="display"></div>
</div>
ontplready — script als de template is ingevoegd
Elk element kan een ontplready -attribuut hebben met JavaScript dat één keer draait zodra de template in het document is ingevoegd. Daarin verwijst this naar dat element. Gebruik het om hulpfuncties aan het rootelement te koppelen in plaats van de globale scope te vervuilen:
<div id="root" ontplready="this._hide_message = () => by_id.message.style.display = \'none\'">
<div id="message">Text text text.</div>
<button type="button" onclick="by_id.root._hide_message()">Hide</button>
</div>
ontplready , en spreek ze aan via by_id. Gebruik je querySelector(), beperk het dan tot de root van de template: by_id.root.querySelector(...) in plaats van document.querySelector(...).Speciale classnamen
Classnamen met het voorvoegsel $ maken van een element een widget die Personyze herkent. De $ -class wordt uit de weergegeven HTML verwijderd.
Herkende speciale classes: $responsive, $btn, $flat_btn, $personyze_button_dont_show_again, $a_add_params, $hint, $icon, $popup, $switch-elem, $cform, $info_lines_scroller, $rating, $table_slider, $table_slider_pagination, $button_add_to_cart.
$responsive
Meestal toegepast op de root van de template. Maakt een data-style -attribuut mogelijk dat een speciale sel(option1, option2) -CSS-functie ondersteunt — Personyze kiest de optie die op het apparaat van de bezoeker de minste overloop veroorzaakt.
<div class="$responsive" data-style="background-color:transparent">
<div data-style="max-width: sel(500px, 80%)">
...
</div>
</div>
Is een pop-uptemplate $responsive maar loopt die toch over, dan past Personyze zoom toe om hem te verkleinen. Gewone style -attributen en <style> -tags werken naast data-style.
$btn
Maakt van het element een knop in Personyze-stijl. Gebruik data-icon="..." voor een icoon vóór de tekst, of data-icon_append="..." voor erna. Iconnamen komen uit Font Awesome 4.
<a class="$btn" data-icon="bullhorn" href="javascript:" onclick="alert(this.dataset.message)" data-message="${args->message:html:default(Hello)}" style="text-decoration:none; padding:0.1em 0.3em">
Show message
</a>
$personyze_button_dont_show_again
Sluitknop die de actie onderdrukt voor het ingestelde aantal sessies. De attributen data-action_id en data-n_sessions koppelen hem:
<img src="https://counter.personyze.com/images/close-buttons/black-16x16.png"
style="width:16px; height:16px"
class="$personyze_button_dont_show_again"
data-action_id="${action_id}"
data-n_sessions="1">
Meestal gecombineerd met een ${menu} -item van type='dontshowagain' zodat het uiterlijk van de sluitknop in de interface kan worden bewerkt.
$a_add_params
Voegt URL-parameters toe aan alle <a> -links in de template. Handig voor advertentietracking. Geef de parameters op in data-json-params:
<div class="$responsive $a_add_params" data-json-params="${args->url_params:html}">
...
</div>
${menu name=\'Frame\', icon=\'th-large\'}
${menu args->url_params name=\'URL additional parameters\', type=\'external_media_url_params\'}
$hint
Toont een tooltip bij hover. De tekst van de tooltip komt uit title="...", of — voor HTML-content — uit een genest element gemarkeerd met data-content="1":
<a href="https://example.com/" class="$hint" data-popup_style="background-color:gold; color:purple; padding:1em">
<span data-content="1">
This is <b>Example</b> site.
</span>
Link
</a>
$icon
Geeft een icoon uit Font Awesome 4 weer. De iconnaam staat in het class-attribuut naast $icon:
<i class="$icon envelope"></i>
<i class="$icon ${args->icon_name:html:default(envelope)}" style="font-size:125%; color:crimson"></i>
${menu args->icon_name name=\'Icon\', type=\'icon\'}
$popup
Toon een pop-up als de gebruiker op een triggerelement klikt (of eroverheen gaat). De pop-up verwijst naar zijn trigger via id:
<div>
<a href="javascript:" id="trigger_1">More info</a>
<div id="popup_1" class="$popup" data-trigger_id="trigger_1" data-is_modal="1"
data-json-trigger_transit=\'{{"template": "animator_fade"}}\'
style="max-width:10em; border:solid 1px; border-radius:5px; background-color:lightgreen; padding:1em">
Blah blah blah blah blah blah blah.
<div>
<a href="javascript:" onclick="by_id.popup_1._hide()">Close</a>
</div>
</div>
</div>
Attributen die het gedrag bepalen: data-trigger_id, data-trigger_onmouseover="1", data-trigger_onfocus="1" (voor invoervelden), data-is_modal="1", data-json-trigger_transit voor animatie (animator_fade, animator_swap_top).
$switch-elem
Een gebied dat kan wisselen tussen alternatieve cases (bijv. een modal in meerdere stappen). Elk kind heeft data-case="case_name"; er is er steeds maar één ingevoegd:
<div id="sw" class="$switch-elem" data-case="step-a" style="position:relative; overflow:hidden">
<div data-case="step-a">
<p>Step A.</p>
<button class="$btn" onclick="by_id.sw._set_case(\'step-b\', null, false, {{template: \'animator_swap_bottom\'}})">Next</button>
</div>
<div data-case="step-b">
<p>Step B.</p>
<button class="$btn" onclick="by_id.sw._set_case(\'step-a\')">Previous</button>
</div>
</div>
JavaScript-methoden op de switch: _set_case(name) (of null om alles te verbergen), _get_case(), _get_cases().
$cform
Een formulier dat data terugstuurt naar Personyze voor het verrijken van bezoekersprofielen, leadverzameling of formulieracties die aan een campagne hangen. De formuliernaam staat in het class-attribuut naast $cform:
<div class="$cform form1" ontplsubmit="personyze.push([\'Submit\', \'${action_id:html}\', this._get_value_ex(), arguments[1], arguments[2]]); return true" ontplaftersubmit="alert(\'Success\')">
<input form="form1" name="Email" type="email" required="1" data-prop-column="email" value="${email:html}">
<button form="form1" type="submit">Submit</button>
</div>
Formulierattributen
data-required_field_message="..."— bericht naast een ontbrekend verplicht veld.data-invalid_value_message="..."— bericht naast een ongeldige invoer.ontplchange="..."— JS dat bij elke waardewijziging draait.ontplsubmit="..."— JS dat bij verzenden draait. Moetarguments[1]()aanroepen bij succes, ofarguments[2](error)bij een fout. Verzenden naar Personyze met:personyze.push(['Submit', '${action_id:html}', this._get_value_ex(), arguments[1], arguments[2]]); return true.ontplaftersubmit="..."— JS dat na een geslaagde verzending draait.
Attributen voor formulierinvoer
Invoervelden die bij het formulier horen, moeten form="form_name" en name="..."hebben. Optionele attributen:
required="1"— het veld moet zijn ingevuld om te kunnen verzenden.pattern="..."— validatie met een reguliere expressie.data-valid_if="..."— JS-expressie die truthy/falsy teruggeeft. Geeft die een tekenreeks terug, dan wordt die als foutmelding getoond.data-prop-prop_name="..."— eigenschappen van de invoer die beschikbaar komen viaform._get_value_ex(). De speciale eigenschapcolumnkoppelt de invoer aan een veld in het Personyze-gebruikersprofiel.data-use_hidden="1"— neem deze invoer ook op als die verborgen is door een form-case-voorwaarde.data-value_if_hidden="..."— vaste waarde voor als het veld verborgen is.
Zichtbaarheid per form-case
Zet optionele groepen invoervelden in een container met data-form_case="..." om ze te tonen/verbergen op basis van andere formulierwaarden:
<div class="$cform form1">
<input form="form1" name="ContactMe" type="checkbox">
<div form="form1" data-form_case="v.ContactMe">
Phone: <input form="form1" name="Phone" type="tel">
</div>
<button form="form1" type="submit">Submit</button>
</div>
JavaScript-methoden op het formulierelement
_get_value()— geeft een plat object terug met invoernamen → waarden._get_value_ex()— geeft invoernamen → objecten terug metvalueplus alledata-prop-*-eigenschappen._set_value(new_value)— stelt waarden in vanuit een object.
Menu-items (instellingen van de visuele editor)
De ${menu} -directives onderaan de template bepalen wat de editor in de interface toont. Er zijn twee typen:
Sectiedirectives
${menu name='Section name', icon='icon-name'}
Parameters: name (label) en optioneel icon (naam uit Font Awesome 4 — veelgebruikte: image, envelope, user, check, times-circle, edit, font).
Itemdirectives
${menu args->arg_name name=\'Argument name\', description=\'...\'}
${menu block->block_name name=\'Block name\', description=\'...\'}
${menu table_alias->column_name name=\'Column name\', description=\'...\'}
Drie vormen — om de waarde van een argument te bewerken, om een voorwaardelijk blok aan of uit te zetten, of om de gebruiker een andere kolom uit een tabel te laten kiezen.
Gecombineerd voorbeeld
${menu name=\'Text\', icon=\'font\'}
${menu args->headline name=\'Headline Text\'}
${menu args->headline_style name=\'Headline Style\', type=\'css\'}
${menu name=\'Close Button\', icon=\'times-circle\'}
${menu args->close_button_style name=\'Close Button Style\', type=\'css\'}
${menu args->close_button name=\'Close Button HTML\', type=\'dontshowagain\'}
De standaardeditor voor een argument is HTML of platte tekst (afhankelijk van of het argument de :html -conversie heeft). Gebruik type='...' om een gespecialiseerde editor te kiezen — zie hieronder.
Typen veldeditors
De meeste editortypen accepteren extra parameters via de notatie param='key=value' in het menu-item.
type='number'
Numerieke invoer. Parameters: min, max, placeholder.
${menu args->n_columns name='Number of columns', type='number', param='min=2', param='max=10', param='placeholder=Columns'}
type='checkbox'
Booleaanse schakelaar. De ingevoegde waarde kan worden aangepast: value_on (standaard 1) en value_off (standaard 0).
<input name="email" ${args->email_required}>
${menu args->email_required name=\'Required Field\', type=\'checkbox\', param=\'value_on=required="1"\', param=\'value_off=style="opacity:0.5"\'}
type='select'
Keuzelijst. Opties als een JSON-array van [label, value] -paren:
${menu args->img_position name='Image Position', type='select', param='options=[["On Top","top"],["On Bottom","bottom"],["On Right Side","right"]]'}
type='textarea'
Tekst over meerdere regels. Parameters: placeholder, autosize (1 om mee te groeien met de content), autosize_max_rows.
type='css'
Visuele CSS-editor. De uitvoer is een style -attribuuttekenreeks. Voeg param='with_responsive=1' toe voor data-style-vriendelijke uitvoer met sel() -functies voor responsieve templates.
${menu args->close_button_style name='Close Button Style', type='css', param='with_responsive=1'}
type='color'
Kleurkiezer. Voegt een CSS-kleurwaarde in:
<div style="background-color: ${args->color}">
...
</div>
${menu args->color name=\'Background color\', type=\'color\'}
type='dontshowagain'
Gespecialiseerde editor voor de HTML van een sluitknop. Hoort bij de $personyze_button_dont_show_again -class.
type='icon'
Iconkiezer (namen uit Font Awesome 4).
type='external_media_url_params'
Editor voor de URL-parameters die worden toegevoegd door $a_add_params.
Kant-en-klare voorbeelden op GitHub
Personyze onderhoudt een bibliotheek met volledig geannoteerde voorbeeldtemplates voor veelvoorkomende patronen. Die staan naast deze naslag op github.com/personyze/personyze-template-language:
Gerelateerde handleidingen
- Bronnen voor developers — overzicht van de REST API en de SDK’s.
- Handleiding voor de JavaScript-actie — voor acties waarin je direct JavaScript schrijft in plaats van templates te gebruiken.
- Handleiding voor de actie Pop-up & banner — uitleg over de visuele editor, als aanvulling op deze naslag.
- Contentvariaties — voorwaarden gebruiken op het niveau van doelgroeptargeting (in plaats van op het niveau van de template).
- Dynamische CRM-variabelen in content — CRM-data invoegen met dezelfde
${variable}-syntaxis.