Динамический контент¶
В теме и теле email рассылок можно использовать FreeMarker — механизм шаблонизации. С его помощью можно управлять динамическим контентом писем.
Есть три вида разметки:
${...}
: будет заменено на значение или выражение, указанное внутри фигурных скобок.<#tag>
- теги: похожи на HTML, но название начинается с#
.<#-- ... -->
- комментарии: не попадут в конечное письмо, в отличии от комментариев HTML.
Вывод значений и выражений¶
Для вывода значений используется разметка ${...}
. В данном примере мы
использовали атрибуты name
и email
объекта contact
<html lang="en">
<body>
<h1>Hi, ${contact.name}</h1>
<p>Thanks for registration!</p>
<p>If you need help visit <a href="https://example.com/help?email=${contact.email}">Help</a> page</p>
</body>
</html>
Для пользователя John Doe
с адресом электронной почты john@customer.net
HTML письма примет следующий вид:
<html lang="en">
<body>
<h1>Hi, John Doe</h1>
<p>Thanks for registration!</p>
<p>If you need help visit <a href="https://example.com/help?email=john@customer.net">Help</a> page</p>
</body>
</html>
Для проведения расчётов можно использовать выражения прямо внутри ${}
:
<html lang="en">
<body>
<h1>${contact.name?capitalize}, special offer!</h1>
<p>Buy goods in the category "Everything for home"
with a ${(1 + contact.loyalty_discount_rate)*20}% discount!</p>
</body>
</html>
В данном примере loyalty_discount_rate
– пользовательский атрибут контакта, в
котором указывается коэффициент повышения процента скидки для каждого контакта.
И чтобы рассчитать конечную скидку, мы умножаем её на базовую скидку в 20%.
Поддерживаемые выражения¶
Ниже мы указали самые популярные выражения, подробнее смотрите в документации по freemarker.
- Переменные. Вывод значения переменной - основной вид использования
динамического контента в сообщениях и письмах. Помимо
contact
, можно создавать свои переменные - Работа со списками.
- используйте
EventInfoList[0]
для получения доступа к любому элемента из списка. ?first
,?last
возвращают первый и последний элементы списка.?join(sep)
объединяет все элементы списка:my list: ${list?join(",")}} // Output my list: 0,1,2,3
?min
,?max
возвращают наименьший и наибольший объект списка.?size
- число элементов в списке.
- используйте
-
Строки.
?upper_case
,?lower_case
,?capitalize
- все слова в строке будут приведены к верхнему или нижнему регистру или будут начинаться с прописной буквы.?length
рассчитывает длину строки.-
?truncate
обрезает текст до указанной длины:-
${"Women Shoes"?truncate(10)} -> "Women[...]"
, потому что данная функция в после обрезания строки прибавляет[...]
-
${product.name?truncate(5, '---')} -> "Wo---"
-
-
Числа.
?round
округляет до ближайшего целого числа. Если оно заканчивается на 0.5, оно округляется в большую сторону.?floor
округляет число в меньшу сторону.?ceiling
округляет число в бошьшую сторону.?string
используется для перевода числа в строку и форматирования чисел.
Определение переменных¶
Создание произвольной переменной и присвоение ей значения:
<#assign positionSum = 4200000>
- создает числовую переменную,<#assign subscriberTitle = "Attention">
- создает строковую переменную.
Математические операции¶
Могут быть использованы чтобы:
- рассчитать размер скидки в рублях,
- рассчитать размер скидки в процентах,
- рассчитать, сколько подписчику необходимо накопить баллов для перехода на следующий шаг программы лояльности,
- пересчитать цены с учетом персональной скидки.
Примеры:
${positionSum * 0.50}
${positionSum * 0.25 / 100}%
<p class="sale">${(product.oldPrice-product.price)/product.oldPrice*100}%</p>
Форматирование чисел¶
Преобразование вывода и округление.
Если требуется выводить размер скидки с одним разрядом после запятой, чтобы не получить значение 12.23472100012%.
- Для примера берем price = 12.234721
${price?string["0"]}
- выведет 12${price?string["0.#"]}
- выведет 12.2${price?string["0.##"]}
- выведет 12.23${price?string["0.###"]}
- выведет 12.235${price?string["0.####"]}
- выведет 12.2347
Теги¶
Логические условия¶
Допустимы следующие логические конструкции:
<#if condition>
...
<#elseif condition2>
...
<#elseif condition3>
...
...
<#else>
...
</#if>
Пример с незаполненным именем подписчика
Например, если нужно вывести имя подписчика, то можно вывести его так:
"Привет, ${contact.name}!"
При отсутствии имени у подписчика, он увидит текст с лишними запятой и пробелом
"Привет, !"
Подходящие варианты:
"Привет<#if (contact.name?length>1)>, ${contact.name?capitalize}<!--#if-->!"
"Привет<#if contact.name??>, ${contact.name?capitalize}<!--#if-->!"
"Привет<#if contact.name?has_content>, ${contact.name?capitalize}<!--#if-->!"
Пример с выводом/сокрытием блока для подписчиков по условию
В письме магазина товаров для животных должно содержаться 3 баннера. Владельцу собаки не нужно показывать баннер, который подойдет владельцу кошки или попугая.
Если не указывать условия:
<a href="#"><img src="/banner-dog.png"></a><br />
<a href="#"><img src="/banner-cat.png"></a><br />
<a href="#"><img src="/banner-bird.png"></a>
С условием:
<#if ${contact.pet}="собака">
<a href="#"><img src="/banner-dog.png"></a>
<#else>
<a href="#"><img src="/banner-cat.png"></a>
<a href="#"><img src="/banner-bird.png"></a>
</#if>
Циклы¶
Пример вывода массива товаров для триггеров
Верстальщик оформляет код одной карточки товаров, который с помощью цикла можно размножить по количеству выбранных для вывода в письме товаров.
<#list contact.EventInfoList as event>
<div class="product">
<a href="${event.productURL}"><img src="${event.productImg}" /></a>
<p class="product-title"><a href="${event.productURL}">${event.productName}</a></p>
<p class="product-price"><a href="${event.productURL}">Цена ${event.productPrice} руб.</a></p>
</div>
</#list>
Пример фильтра в цикле
Клиент решает не показывать подписчикам товары дешевле 1500 рублей.
<#list contact.EventInfoList as event>
<#if ${event.productPrice}<1500 ><#continue></#if>
<div class="product"><a href="${event.productURL}"><img src="${event.productImg}" /></a>
<p class="product-title"><a href="${event.productURL}">${event.productName}</a></p>
<p class="product-price"><a href="${event.productURL}">Цена ${event.productPrice}} руб.</a></p>
</#list>
Пример проверки на наличие значений в цикле
Если цикл пустой - вывести сообщение о том, что нет товаров.
<#list contact.EventInfoList as event>
<div class="product"><a href="${event.productURL}"><img src="${event.productImg}" /></a>
<p class="product-title"><a href="${event.productURL}">${event.productName}</a></p>
<p class="product-price"><a href="${event.productURL}">Цена ${event.productPrice}} руб.</a></p>
<#else>
No products
</#list>
Пример добавления разделителя между элементами цикла
Для добавления разделителя между элементами цикла можно использовать директиву
<#sep>
, которая добавлет код после каждого элемента цикла, кроме последнего.
<#list contact.EventInfoList as event>
<p class="categoryTitle"><a href="${event.categoryUrl}">${event.categoryTitle}</a></p>
<#sep>, </#sep>
</#list>
Отмена отправки сообщения¶
В некоторых ситуациях, особенно при обработке
событию с вашего сайта, может понадобиться отмена отправки.
Для этого используйте функцию cancelMessage(reason)
в комбинации с проверкой
по условию <#if>
:
<html lang="en">
<body>
<#if ${contact.loyalty_level} == 0>
<#return cancelMessage("Низкий loyalty_level") />
<#/if>
<h1>${contact.name?capitalize}, special offer!</h1>
<p>Buy goods in the category "Everything for home"
with a ${(1 + contact.loyalty_discount_rate)*20}% discount!</p>
</body>
</html>
Объект "Contact"¶
Contact
- объект, доступный в тексте сообщений и писем как contact
для
предоставления доступа к контактной информации из
базы контактов.
Для доступа к атрибуту контакта вызовите его через точку: contact.attr
.
Базовые атрибуты контакта:
name
- имя,surname
- фамилия,phone
- номер телефона,email
- адрес электронной почты,gender
- пол с возможными значениямиgender.male
иgender.female
,country
- страна,city
- город,birthdate
- дата рождения,creationDate
- дата с временем создания контакта,lastUpdate
- дата с временем последнего изменения контакта,
Tip
Доступ возможен не только к базовым, но и пользовательским атрибутам.
Если сообщение отправляется по событию с вашего сайта, то
у контата становится доступным атрибут EventInfoList
- список передаваемых
с сайта объектов.