#
Custom code
В данном гайде описан процесс создания рекомедательного виджета через кампанию типа Custom code и создания шаблона для последующего его переиспользования.
#
Создание кампании
- Переходим в раздел кампаний и создаем новую кампанию
- Выбирем тип страницы, на котором будет работать кампания
- Выбираем тип кампании Custom Code
- Выбираем шаблон - No template
Откроется экран настроек кампании, на котором вы можете:
- Указать название, добавить метки и описание
- Выбрать триггер (по умолчанию - при загрузке страницы)
- Изменить тип страницы, на котором будет работать кампания
- Указать частотность (по умолчанию - на каждый просмотр страницы)
- Указать запускать ли на каждый SPA-ивент (для SPA-сайтов в большинстве случаев требуется, иначе кампания запустится только при первичной загрузке SPA-приложения)
Экран настроек кампании типа Custom code
Переходим к следующему этапу, нажимая кнопку Next.
Нажимаем на Experince, чтобы открыть его настройки.
Экран настроек экспириенса
Переходим в редактор вариации, кликнув в ее название или иконку редактирования справа.
#
Редактор вариации
Редактор вариации кампании типа Custom Code отличается от редактора других типов кампаний. Здесь нет внутреннего превью и возможности писать напрямую HTML, так как данный тип кампании представляет собой произвольный Javascript код и добавленный к нему CSS.
Переходим в вкладку JS и пишем код.
Для создания рекомендательного виджета нам потребуется как минимум:
- название виджета;
- стратегия;
- количество товаров;
- место и способ вставки виджета.
Объявим для этого константу и создадим переменные:
const CONFIG = {
strategyId: '{{ ERROR }}',
title: '',
maxProducts: Number('{{ ERROR }}'),
selector: '',
insertMethod: '{{ ERROR }}'
};
Переменные создаются путем оборочивания строки в двойные фигурные скобки или нажатием правой кнопки мыши в области кода и нажатием “Add variable” в контекстном меню.
Переменные нужны для того, чтобы затем удобно управлять какими-либо параметрами вариации, а также превратить ее в шаблон в дальнейшем.
После того, как в код добавлены переменные, они также появятся во вкладке Variables редактора кампаний.
Можно перейти туда и отредактировать их, поменяв тип и другие параемтры. Также доступно редактирование переменной при клике в нее в рамках открытого таба с кодом.
Пример переменных и их настроек
Устанавливаем типы переменных:
- Strategy ID → Strategy
- Title → Text
- Products count → Number (от 1 до 50)
- Selector → CSS Selector
- Insert Method → Dropdown (в нем будем хранить способы вставки After, before, replace, заполним позже)
#
Получение товаров
Далее нам потребуется функция, которая будет получать JSON с рекомендованными товарами:
function getRecs() {
return new Promise((resolve, reject) => {
GF.Recommendations.get(CONFIG.strategyId, {
maxProducts: CONFIG.maxProducts
}, function(err, data) {
if (err) {
return reject(false);
}
return resolve(data);
})
})
}
Вызываем функцию и обрабатываем полученный результат.
Для этого мы ждём определенный элемент на странице, куда планируем вставить виджет и когда он появляется — запрашиваем рекомендации и встраиваем их.
GF.waitForElement(CONFIG.selector, elements => {
getRecs().then(data => {
// process data
});
})
Можно делать наоборот — сначала запрашивать рекомендации, а после ожидать элемент для уменьшения задержки отображения виджета, так как в любом случае это запрос к серверу и он требует времени.
#
Рендер виджета
В случае успешного ответа рекомендательной стратегии, в data
будет массив slots
, представляющий собой набор товаров, которые нужно отрисовать в виджете. Как именно это сделать полностью зависит от вас, но для примера можно использовать следующий код:
function getHtml(data) {
let html = `
<div class="demo-recs__title">${CONFIG.title}</div>
<div class="demo-recs">
`;
const itemTemplate = getProductItemTemplate();
for (let i = 0; i < data.slots.length; i++) {
html += itemTemplate.replace(/{([^{}]+)}/g, function (keyExpr, key) {
return data.slots[i].item[key] || "";
});
}
html += '</div>';
return html;
}
function getProductItemTemplate() {
return `
<a href="{url}" class="gf-recs__item">
<img src="{image_url}">
<div class="gf-recs__price"><span class="gf-recs__price-num">{price}</span></div>
<div class="gf-recs__name">{name}</div>
</a>
`;
}
Функция getHtml
генерирует HTML-код для будущего виджета. Для этого используется вспомогательная функция getProductItemTemplate
, которая возвращает HTML отдельного товара и в цикле происходит замена товарных переменных на данные, которые пришли из ответа стратегии. При данной реализации важно чтобы товарные переменные, объявленные в одинарных фигурных скобках точно соответствовали названию колонок в товарном фиде.
Теперь мы можем использовать это для нашей функции и попробовать вставить в DOM:
GF.waitForElement(CONFIG.selector, elements => {
getRecs().then(data => {
if (data && data.slots && data.slots.length === 0) {
// обработка пустого ответа стратегии, если требуется
}
const html = getHtml(data);
elements[0].insertAdjacentHTML('afterend', html);
});
})
Если все сделано правильно и переменные заполнены — вы увидите вставленный виджет (без CSS он будет выглядеть плохо — это нормально и в рамках данного гайда мы не будем заниматься версткой).
Далее вернемся к переменной CONFIG.insertMethod
, которую ранее планировали сделать с типом Dropdown. Давайте зададим ей следующие значения и заменим код вставки:
// вместо строчки elements[0].insertAdjacentHTML('afterend', html);
elements[0].insertAdjacentHTML(CONFIG.insertMethod, html);
На данном этапе мы уже можем вставлять виджет на страницу с определенным заголовком и количеством товаров, указав CSS selector в значении соответствующей переменной.
#
Сбор аналитических данных
Теперь необходимо сделать так, чтобы можно было собирать аналитические данные по виджету и затем увидеть их в отчете. Для этого требуется добавить определенные дата-атрибуты при генерации HTML и после отрисовки вызвать метод трекинга.
GF.Recommendations.track(element, {
var: '${slVariationId}',
ver: '${slVersionId}',
exp: '${slExperienceId}',
cam: '${slTagId}',
})
Конечный код может выглядеть следующим образом:
const CONFIG = {
strategyId: '{{ ERROR }}',
title: '',
maxProducts: Number('{{ ERROR }}'),
selector: '',
insertMethod: '{{ ERROR }}'
};
GF.waitForElement(CONFIG.selector, elements => {
getRecs().then(data => {
if (data && data.slots && data.slots.length === 0) {
// обработка пустого ответа стратегии, если требуется
}
const html = getHtml(data);
elements[0].insertAdjacentHTML(CONFIG.insertMethod, html);
const inertedElement = document.querySelector('.demo-recs');
GF.Recommendations.track(inertedElement, {
var: '${slVariationId}',
ver: '${slVersionId}',
exp: '${slExperienceId}',
cam: '${slTagId}',
})
});
})
function getRecs() {
return new Promise((resolve, reject) => {
GF.Recommendations.get(CONFIG.strategyId, {
maxProducts: CONFIG.maxProducts
}, function (err, data) {
if (err) {
return reject(false);
}
return resolve(data);
})
})
}
function getProductItemTemplate() {
return `
<a
href="{url}"
class="gf-recs__item"
data-sl-product-fallback="{fallback}"
data-sl-product-id="{sku}"
data-sl-strategy-id="{strId}"
data-sl-product-slot="{slot}"
>
<img src="{image_url}">
<div class="gf-recs__price"><span class="gf-recs__price-num">{price}</span></div>
<div class="gf-recs__name">{name}</div>
</a>
`;
}
function getHtml(data) {
const mappedProducts = data.slots.map(function (el, i) {
el.item.strId = el.strId;
el.item.fallback = el.fallback;
el.item.slot = i;
return el.item;
});
let html = `
<div class="demo-recs__title">${CONFIG.title}</div>
<div class="demo-recs"
data-sl-widget-id="${data.wId}"
data-sl-feed-id="${data.fId}"
data-sl-widget-fallback="${data.fallback}"
>
`;
const itemTemplate = getProductItemTemplate();
for (let i = 0; i < mappedProducts.length; i++) {
html += itemTemplate.replace(/{([^{}]+)}/g, function (keyExpr, key) {
return mappedProducts[i][key] || "";
});
}
html += '</div>';
return html;
}
#
Создание шаблона
Когда пишется код, создается определенная кампания или вариация, есть вероятность того, что нужно будет переиспользовать. Например, создать AB-тест с тремя вариациями, которые отличаются цветом или используемой рекомендательной стратегией. Для этого используются шаблоны, которые позволяют оптимизировать процесс, как со стороны разработчика, так и со стороны бизнес-пользователя платформы. Кроме того, шаблоны уменьшают размер скрипта за счёт того, что код шаблона не дублируется множество раз в рамках каждой из вариации, где он используется.
После того, как написан код и созданы необходимые переменные можно нажать кнопку “Save as Template” в правом верхнем углу интерфейса создания вариации. Появится всплывающее окно, в котором можно задать название шаблона и сохранить текущий код и переменные как шаблон.
После сохранения шаблона блокируется возможность изменять код непосредственно в вариации. Чтобы изменить код — нужно либо отвязать шаблон от вариации, либо перейти в раздел Assets/Templates и отредактировать код шаблона.
При создании новой вариации можно выбирать из двух типов шаблонов:
Custom templates — это шаблоны, которые вы создали в рамках секции. При выборе такого шаблона он связывается с вариацией.
Gravity Templates — это шаблоны, которые созданы в рамках платформы Gravity Field, они не связываются с вариацией и вставляются просто как код. Вы можете адаптировать их под свои цели и затем сохранить как собственный шаблон, который станет доступен в рамках раздела Custom Templates.