Las acciones de Personyze — banners, popups, widgets de recomendación, emails y más — se diseñan normalmente de forma visual en el editor de campañas. Pero detrás de cada editor visual hay código fuente HTML con las directivas de plantilla de Personyze, y puede editar ese HTML directamente cuando necesite un control más fino. Este artículo es la referencia completa del lenguaje de plantillas.
El lenguaje es HTML y CSS normales, con algunos añadidos:
- Directivas de preprocesado entre
${...}— variables, condicionales, bucles y funciones que se evalúan en el servidor antes de enviar el HTML a la página. - Nombres de clase especiales (con el prefijo
$) que convierten elementos normales en widgets de Personyze — botones, popups, áreas conmutables, formularios condicionales y más. - Directivas de menú al final de la plantilla, que definen los controles del editor visual que ve alguien que no es desarrollador en la GUI.
Directivas de preprocesado
Un signo de dólar seguido de llaves indica una directiva de preprocesado. El contenido de las llaves se evalúa y se sustituye por el resultado antes de entregar el HTML al navegador. Dentro de las llaves puede usar una variable, una llamada a función sobre una variable o cualquiera de las directivas estructurales que se describen más abajo.
${some_variable}
La directiva puede producir texto que a su vez contiene otra directiva — Personyze evalúa en dos pasadas:
- Pasada de preprocesado — sustituye las variables de argumento
${args->...}en la plantilla. - Pasada de usuario — sustituye las variables de cada usuario (
${first_name},${country_code}, etc.) para cada visitante.
Variables de preprocesado (args)
Para crear una variable de preprocesado — la que aparece como campo editable en la GUI visual — declárela una vez al final de la plantilla con una directiva ${menu} y haga referencia a ella en cualquier parte del cuerpo de la plantilla con ${args->name}:
<p title="${args->main_text:html}">
${args->main_text}
</p>
${menu args->main_text name=\'Main text\'}
Ahora la GUI muestra un campo editable «Main text». Lo que el usuario escriba ahí se inserta tanto dentro de la etiqueta <p> como en su atributo title (con los caracteres especiales de HTML escapados mediante la conversión :html para que el valor no pueda salirse del atributo e inyectar etiquetas adicionales).
Sintaxis de las expresiones de argumento
La forma general es la palabra clave args , una flecha, el nombre de la variable y después cero o más conversiones precedidas de dos puntos:
${args->variable_name:function1:function2(parameter)}
Variables del perfil de usuario
La segunda pasada sustituye valores de cada usuario. Personyze incluye estas variables de perfil integradas:
first_namelast_nameemailindustry
También puede definir campos de perfil personalizados y recoger valores para ellos mediante formularios o la API. Una vez definidos, están disponibles de la misma manera:
${first_name:default('User')}
Las variables de preprocesado pueden producir texto que contiene variables de usuario de la segunda pasada. Use apóstrofos duplicados para los valores por defecto anidados:
<p>
${args->main_text:default(\'Dear, ${first_name:default(\'\'User\'\')}\')}
</p>
${menu args->main_text name=\'Main text\'}
Variables de sesión y de página
Variables que dependen de la sesión de navegación y del dispositivo actuales del visitante:
| Variable | Devuelve |
|---|---|
url_host_port |
Nombre de dominio del sitio. |
url_path |
Ruta de la URL (la parte después del nombre de dominio). |
ur |
La URL completa de la página actual. |
country_code |
Código de país de dos letras (p. ej. US, DE). |
city |
Nombre de la ciudad. |
lang_0 |
Idioma principal del navegador. |
known_device_type |
regular (escritorio), tablet, o phone. |
is_returning_user |
0 para usuarios nuevos, 1 para los que vuelven. |
landing_url |
URL de la página de entrada con la que empezó esta sesión. |
landing_host_port |
Parte de dominio de la página de entrada. |
landing_path |
Parte de ruta de la URL de la página de entrada. |
part_of_day() |
morning, afternoon, evening, o night. |
weekday |
Día de la semana como número: 0 = domingo, 1 = lunes, …, 6 = sábado. |
day |
Día del mes. |
last_month_day |
Último día del mes actual — 28, 29, 30 o 31. |
Funciones
Las funciones se aplican a las variables con la sintaxis de prefijo de dos puntos:
${variable:func_name}
${variable:func_name(parameter)}
${variable:func_name(\'parameter\')}
${variable:func_name(\'param1\', \'param2\', \'param3\')}
Si un parámetro contiene comas, apóstrofos o paréntesis de cierre — o si hay más de un parámetro — debe ir entre comillas. Para representar un apóstrofo dentro de una cadena entre comillas, duplíquelo: :func_name('I''m a string').
Cadenas y HTML
| Función | Descripción |
|---|---|
html |
Escapa los caracteres especiales de HTML: &→&, "→", <→<. Úsela siempre con los valores que se insertan en atributos o en cualquier lugar donde el contenido aportado por el usuario no deba interpretarse como marcado. |
default |
Para las variables args : indica el valor actual o inicial. Para las variables del perfil de usuario: indica un valor alternativo si la variable está vacía. Con args, póngala solo en una aparición aunque la variable aparezca varias veces. |
json |
Convierte el valor en JSON. Útil para incrustar con seguridad datos arbitrarios en JavaScript: onclick="alert(${p->title:json:html})". |
url |
Codifica para URL (p. ej. ? → %3F). |
lc |
Minúsculas: ${p->title:lc}. |
uc |
Mayúsculas. |
replace |
Sustituye todas las apariciones de una subcadena por otra: ${url:replace('http://', 'https://')}. |
regexp_replace |
Sustituye mediante una expresión regular. |
ellipsis |
Trunca a los N primeros caracteres y añade … si se ha recortado algo: ${p->description_long:ellipsis(50)}. |
left |
Los N primeros caracteres (sin puntos suspensivos). |
right |
Los N últimos caracteres. |
substr |
A partir del carácter N, extrae M caracteres. |
substring |
Subcadena del carácter N al carácter M (exclusive). |
text_after |
Texto después de una palabra o subcadena indicada. |
text_before |
Texto antes de una palabra o subcadena indicada. |
Formato de números y precios
| Función | Descripción |
|---|---|
sprintf |
Da formato a un número con marcadores. %s para el valor sin formato, %f como número, o %[#,###.##]f para controlar por completo los millares y los decimales. # es un dígito opcional, 0 es obligatorio. Use g en lugar de f para omitir los ceros finales en los números enteros. Dígitos arábigos mediante ٠ como marcador. |
price |
Da formato de precio con el formato numérico de su cuenta. Dos formatos predefinidos: :price para el predeterminado, :price('alternative') para el segundo. La GUI ofrece un control para definir ambos. |
round |
Redondea al más cercano. |
floor |
Redondea hacia menos infinito. |
ceil |
Redondea hacia más infinito. |
truncate |
Descarta la parte fraccionaria. |
Recorrer tablas de Personyze (${foreach})
Las tablas de Personyze — su catálogo de productos, su catálogo de artículos, los intereses de usuario calculados — se recorren con ${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}
Los widgets de recomendación usan este patrón para mostrar las tarjetas reales de productos o contenidos. El algoritmo de recomendación elegido en la GUI determina el nombre de la tabla y los filtros que aparecen en la plantilla. Ejemplo para «los más vendidos en el periodo reciente»:
${foreach sum_products as p where p->for_period=\'recently\' and p->n_goal>0 order by p->n_goal desc limit 12}
...
${end}
Puede tener varios bucles ${foreach} en una plantilla, incluso anidados. Si uno de ellos tiene el alias main, el selector de algoritmo de recomendación de la GUI controla ese bucle. Si no, controla el primero que encuentre.
El producto que se está viendo
Si en la página actual se notifica un evento de visualización de producto, puede acceder a los datos del producto que se está viendo directamente mediante viewing_product — sin ${foreach} de por medio:
You're interested in ${viewing_product->color} color.
Otras tablas de una sola fila disponibles automáticamente:
viewing_product— el producto que se está viendo (si se notificó un evento de visualización en esta página).last_viewed_product— el producto visto más recientemente en la sesión del visitante.last_extra_product— el producto añadido al carrito más recientemente.
Directivas condicionales
${if} / ${else if} / ${else}
Incluya partes de la plantilla según una variable de preprocesado, una variable de perfil o una columna de tabla:
${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}
Las expresiones condicionales pueden hacer referencia a args, lo que permite filtros controlables por el usuario:
${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}
Dos formas — booleana (cada when es su propia condición) y de expresión (cada when se compara con la expresión del caso):
${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}
Bloques condicionales (activables en la GUI)
Los bloques condicionales son elementos HTML marcados con ${block->block_name}. La GUI muestra un interruptor que activa o desactiva el bloque — útil para opciones del tipo «con botón / sin botón».
${block->with_button:default(0)}
<div>
<button type="button">See more</button>
</div>
${menu block->with_button name=\'With button\'}
Estructura HTML y by_id
Las plantillas pueden contener cualquier HTML — incluidas las etiquetas <style> . Se aplican algunas transformaciones:
id : atributos eliminados, pero accesibles mediante by_id
Si su plantilla tiene elementos con atributos id , esos atributos se eliminan antes de mostrarla (para evitar colisiones con otro marcado de la página). Pero puede seguir haciendo referencia a esos elementos mediante un objeto especial by_id disponible en los manejadores onclick y un atributo ontplready especial:
<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 al montar la plantilla
Cualquier elemento puede tener un atributo ontplready con JavaScript que se ejecuta una vez insertada la plantilla en el documento. Dentro de él, this hace referencia a ese elemento. Úselo para vincular funciones auxiliares al elemento raíz en lugar de contaminar el ámbito global:
<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 y acceda a ellas a través de by_id. Cuando use querySelector(), limítelo a la raíz de la plantilla: by_id.root.querySelector(...) en lugar de document.querySelector(...).Nombres de clase especiales
Los nombres de clase con el prefijo $ convierten un elemento en un widget de Personyze. La clase $ se elimina del HTML resultante.
Clases especiales reconocidas: $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
Suele aplicarse a la raíz de la plantilla. Habilita un atributo data-style que admite la función CSS especial sel(option1, option2) — Personyze elige la opción que provoca menos desbordamiento en el dispositivo del visitante.
<div class="$responsive" data-style="background-color:transparent">
<div data-style="max-width: sel(500px, 80%)">
...
</div>
</div>
Si una plantilla de popup es $responsive pero sigue desbordándose, Personyze aplica zoom para reducirla. Los atributos style normales y las etiquetas <style> funcionan junto con data-style.
$btn
Convierte el elemento en un botón con el estilo de Personyze. Use data-icon="..." para un icono antes del texto, o data-icon_append="..." para después. Los nombres de los iconos son los de 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
Botón de cerrar que suprime la acción durante el número de sesiones configurado. Los atributos data-action_id y data-n_sessions lo conectan:
<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">
Suele ir acompañado de un elemento ${menu} de type='dontshowagain' para que el aspecto del botón de cerrar se pueda editar en la GUI.
$a_add_params
Añade parámetros de URL a todos los enlaces <a> de la plantilla. Útil para el seguimiento de anuncios. Indique los parámetros en 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
Muestra un tooltip al pasar el cursor. El texto del tooltip sale de title="...", o — para contenido HTML — de un elemento anidado marcado con 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
Muestra un icono de Font Awesome 4. El nombre del icono va en el atributo class, junto a $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
Muestra un popup cuando el usuario hace clic (o pasa el cursor) sobre un elemento activador. El popup hace referencia a su activador por 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>
Atributos que controlan el comportamiento: data-trigger_id, data-trigger_onmouseover="1", data-trigger_onfocus="1" (para campos de entrada), data-is_modal="1", data-json-trigger_transit para la animación (animator_fade, animator_swap_top).
$switch-elem
Un área que puede alternar entre casos distintos (p. ej., un modal de varios pasos). Cada hijo tiene data-case="case_name"; solo se monta uno a la vez:
<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>
Métodos de JavaScript del conmutador: _set_case(name) (o null para ocultarlos todos), _get_case(), _get_cases().
$cform
Un formulario que envía datos a Personyze para enriquecer el perfil del visitante, captar leads o acciones de formulario vinculadas a campañas. El nombre del formulario va en el atributo class, junto a $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>
Atributos del formulario
data-required_field_message="..."— mensaje que se muestra junto a un campo obligatorio vacío.data-invalid_value_message="..."— mensaje que se muestra junto a un valor no válido.ontplchange="..."— JS que se ejecuta con cada cambio de valor.ontplsubmit="..."— JS que se ejecuta al enviar. Debe llamar aarguments[1]()si todo va bien o aarguments[2](error)si falla. Envíe a Personyze con:personyze.push(['Submit', '${action_id:html}', this._get_value_ex(), arguments[1], arguments[2]]); return true.ontplaftersubmit="..."— JS que se ejecuta después de un envío correcto.
Atributos de los campos del formulario
Los campos que pertenecen al formulario deben tener form="form_name" y name="...". Atributos opcionales:
required="1"— el campo debe rellenarse para poder enviar.pattern="..."— validación con expresión regular.data-valid_if="..."— expresión JS que devuelve verdadero o falso. Si devuelve una cadena, esa cadena se muestra como mensaje de error.data-prop-prop_name="..."— propiedades del campo que se exponen medianteform._get_value_ex(). La propiedad especialcolumnasocia el campo a un campo del perfil de usuario de Personyze.data-use_hidden="1"— incluir este campo aunque lo oculte una condición de caso del formulario.data-value_if_hidden="..."— valor fijo que se usa cuando el campo está oculto.
Visibilidad por casos del formulario
Envuelva los grupos de campos opcionales en un contenedor con data-form_case="..." para mostrarlos u ocultarlos según otros valores del formulario:
<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>
Métodos de JavaScript del elemento de formulario
_get_value()— devuelve un objeto plano de nombres de campo → valores._get_value_ex()— devuelve nombres de campo → objetos convaluemás todas sus propiedadesdata-prop-*correspondientes._set_value(new_value)— define los valores a partir de un objeto.
Elementos de menú (controles del editor visual)
El identificador de cliente ${menu} — las directivas al final de la plantilla definen lo que muestra el editor de la GUI. Hay dos tipos:
Directivas de sección
${menu name='Section name', icon='icon-name'}
Parámetros: name (etiqueta) y, opcionalmente, icon (nombre de Font Awesome 4 — los más comunes: image, envelope, user, check, times-circle, edit, font).
Directivas de elemento
${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=\'...\'}
Tres formas — para editar el valor de un argumento, para activar o desactivar un bloque condicional, o para que el usuario elija otra columna de una tabla.
Ejemplo combinado
${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\'}
El editor predeterminado de un argumento es HTML o texto sin formato (según si el argumento tiene la conversión :html ). Use type='...' para elegir un editor especializado — véase más abajo.
Tipos de editor de campo
La mayoría de los tipos de editor aceptan parámetros adicionales mediante la notación param='key=value' en el elemento del menú.
type='number'
Campo numérico. Parámetros: min, max, placeholder.
${menu args->n_columns name='Number of columns', type='number', param='min=2', param='max=10', param='placeholder=Columns'}
type='checkbox'
Interruptor booleano. El valor insertado se puede personalizar: value_on (por defecto 1) y value_off (por defecto 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'
Desplegable. Opciones como un array JSON de pares [label, value] así:
${menu args->img_position name='Image Position', type='select', param='options=[["On Top","top"],["On Bottom","bottom"],["On Right Side","right"]]'}
type='textarea'
Texto de varias líneas. Parámetros: placeholder, autosize (1 para crecer con el contenido), autosize_max_rows.
type='css'
Editor visual de CSS. El resultado es una cadena de atributo style . Añada param='with_responsive=1' para producir un resultado compatible con data-style, con funciones sel() para plantillas adaptables.
${menu args->close_button_style name='Close Button Style', type='css', param='with_responsive=1'}
type='color'
Selector de color. Inserta un valor de color CSS:
<div style="background-color: ${args->color}">
...
</div>
${menu args->color name=\'Background color\', type=\'color\'}
type='dontshowagain'
Editor especializado para el HTML del botón de cerrar. Se usa junto a la clase $personyze_button_dont_show_again de la plantilla.
type='icon'
Selector de iconos (nombres de Font Awesome 4).
type='external_media_url_params'
Editor de los parámetros de URL que añade $a_add_params.
Ejemplos listos para usar en GitHub
Personyze mantiene una biblioteca de plantillas de ejemplo con anotaciones completas que cubren los patrones más comunes. Están junto a esta referencia en github.com/personyze/personyze-template-language:
Guías relacionadas
- Centro de recursos para desarrolladores — resumen de la API REST y los SDK.
- Guía de la acción JavaScript — para acciones en las que escribe JavaScript directamente en lugar de usar plantillas.
- Guía de la acción de popup y banner — recorrido por el editor visual que complementa esta referencia.
- Variaciones de contenido — uso de condicionales a nivel de segmentación de audiencia (frente al nivel de plantilla).
- Variables dinámicas del CRM en el contenido — insertar datos del CRM con
${variable}(la misma sintaxis).