# Использование Liquid-шаблонов

Liquid-шаблоны значительно расширяют возможности персонализации Pushwoosh за счет реализации сложной логики в дополнение к обычному использованию [динамического контента](/ru/developer/guides/personalization/dynamic-content/).

Персонализация сообщений в Pushwoosh основана на [тегах (данных пользователя)](/ru/developer/guides/audience-and-segmentation/tags/). Pushwoosh предлагает множество [тегов по умолчанию](/ru/developer/guides/audience-and-segmentation/tags/#default-tags) и [пользовательских тегов](/ru/developer/guides/audience-and-segmentation/tags/#custom-tags). Используя их, вы можете указать имя пользователя, город, историю покупок и т.д., чтобы отправить более персонализированное сообщение, например: «Привет, `{First_name}`, спасибо за заказ `{item}`».

Liquid-шаблоны добавляют больше логики в динамический контент. Например, если тег подписки пользователя содержит «free», вы можете отправить ему сообщение: «Получите скидку 10%».

Изменение контента сообщения в соответствии с ID, поведением и предпочтениями пользователей — это наиболее эффективный способ повысить релевантность и получить более впечатляющие результаты от ваших маркетинговых кампаний.

## Синтаксис

Шаблоны контента, основанные на [Liquid от Shopify](https://shopify.github.io/liquid/), используют комбинацию [**тегов**](/ru/developer/guides/personalization/liquid-templates/#tags), [**объектов**](/ru/developer/guides/personalization/liquid-templates/#objects) и [**фильтров**](/ru/developer/guides/personalization/liquid-templates/#filters) для загрузки динамического контента. Шаблоны контента позволяют вам получать доступ к определенным переменным из шаблона и выводить их данные, не зная ничего о самих данных.

<Aside type="note">
Чтобы узнать больше о синтаксисе, обратитесь к [документации Liquid](https://shopify.github.io/liquid/basics/introduction/).
</Aside>

### Объекты

`Объекты` определяют контент, который будет отображаться пользователю. `Объекты` должны быть заключены в двойные фигурные скобки: `{{ }}`

Например, при персонализации сообщения отправьте `{{Name}}` в его теле, чтобы добавить имена пользователей в контент сообщения. Имя пользователя (значение тега Name) заменит объект Liquid в сообщении, которое увидит пользователь.

<Tabs>
  <TabItem label="Входные данные">

```

Hi {{Name}}! We're glad you're back!

```

  </TabItem>

  <TabItem label="Результат">
    Привет, Анна! Мы рады, что вы вернулись!
  </TabItem>
</Tabs>


### Теги

`Теги` создают логику и управляют потоком выполнения для шаблонов. Разделители в виде фигурных скобок и процентов `{%` и `%}` и текст, который они окружают, не производят видимого вывода при рендеринге шаблона. Это позволяет вам присваивать переменные и создавать условия или циклы, не показывая пользователю никакой логики Liquid.

Например, используя тег `if`, вы можете изменять язык сообщения в зависимости от того, какой язык установлен на устройстве пользователя:

<Tabs>
  <TabItem label="Входные данные">

```liquid
{% if Language == 'fr' %}
Salut!
{% else %}
Hello!
{% endif %}
````

  </TabItem>

  <TabItem label="Результат (fr)">
    Salut!
  </TabItem>

  <TabItem label="Результат (es)">
    Hello!
  </TabItem>
</Tabs>

### Операторы тегов

<table data-header-hidden><thead><tr><th width="189.5" align="center">Оператор</th><th>Описание</th></tr></thead><tbody><tr><td align="center"><code>==</code></td><td>равно</td></tr><tr><td align="center"><code>!=</code></td><td>не равно</td></tr><tr><td align="center"><code>></code></td><td>больше чем</td></tr><tr><td align="center"><code>&#x3C;</code></td><td>меньше чем</td></tr><tr><td align="center"><code>>=</code></td><td>больше или равно</td></tr><tr><td align="center"><code>&#x3C;=</code></td><td>меньше или равно</td></tr><tr><td align="center"><code>or</code></td><td>логическое «или»</td></tr><tr><td align="center"><code>and</code></td><td>логическое «и»</td></tr><tr><td align="center"><code>contains</code></td><td>проверяет наличие подстроки в строке или массиве строк</td></tr></tbody></table>

<Aside type="note">
В тегах с более чем одним оператором `and` или `or` операторы проверяются в порядке _справа налево_. Вы не можете изменить порядок операций с помощью скобок — скобки являются недопустимыми символами в Liquid и помешают работе ваших тегов.
</Aside>

### Фильтры

`Фильтры` изменяют вывод объекта или переменной Liquid. Они используются внутри двойных фигурных скобок `{{ }}` и при присваивании переменных, и разделяются символом вертикальной черты `|`. К одному выводу можно применить несколько фильтров, они применяются слева направо.


<Tabs>
<TabItem label="Входные данные">

```

{{ Name | capitalize | prepend:"Hello " }}

```

</TabItem>

<TabItem label="Результат">

Hello Anna

</TabItem>
</Tabs>

## Использование Liquid-шаблонов в сообщениях, отправляемых через API

Используйте синтаксис Liquid в ваших запросах [`createMessage`](/ru/developer/api-reference/messages-api/#createmessage) для реализации Liquid-шаблонов. Шаблоны доступны для параметра "content" запроса `createMessage`, а также для любого другого параметра, поддерживающего динамический контент, в частности, для специфичных для платформы параметров "title", "subtitle" и "image".

Используя шаблоны контента, вы можете либо указать данные в ваших API-запросах (передавая параметр "template\_bindings"), либо получить данные из значений тегов, хранящихся на устройствах пользователей (не используя параметр "template\_bindings"). Таким образом, вы можете создавать пуш-кампании на основе данных о пользователях, содержащие чрезвычайно релевантный контент.

<Aside type="note">
Обратите внимание, что в отличие от динамического контента, переменные в шаблонах должны быть заключены в двойные фигурные скобки следующим образом: `{{myVariable}}`.
</Aside>

Чтобы определить логику шаблона с использованием тегов с пробелами в их именах, используйте следующую технику:

**Пример**

```
{% capture my_tag %}{{My Tag}}{% endcapture %}
{% if my_tag == 'value' %}
Контент для отправки в этом случае
{% else %}
Контент для отправки в противном случае
{% endif %}
```
## Примеры использования Liquid-шаблонов

Здесь вы найдете несколько примеров использования Liquid-шаблонов.

### Многоязычные пуши

Liquid-шаблоны позволяют точно указать, на каком языке пользователи должны получать ваши пуш-уведомления. Посмотрите на простой пример API-запроса и полученного сообщения в зависимости от используемых в запросе привязок шаблона.


<Tabs>
<TabItem label="Liquid-шаблон">

```

{% if Language == 'es' %}
¡Hola!
{% else %}
Hello!
{% endif %}

````

</TabItem>

<TabItem label="API-запрос">

```javascript
{
  "request": {
    "application": "XXXXX-XXXXX", // Код приложения Pushwoosh
    "auth": "yxoPUlw.....IyEX4H", // Токен доступа API из панели управления Pushwoosh
    "notifications" : [ // параметры пуш-уведомления
      {
       "content": "{% raw %}
{% if language == 'es' %}¡Hola!{% else %}hello!{% endif %}
{% endraw %}",
        "template_bindings": { // опционально. Если в запросе не переданы template_bindings, используются значения тегов с устройства.
         "language" : "es"
        }
      }
    ]
  }
}
````

</TabItem>

<TabItem label="Результат">

**Язык 'es'**:
¡Hola!

**Язык 'en'**:
Hello!

</TabItem>
</Tabs>


### Предложение обновить подписку

Поощряйте ваших клиентов обновлять подписку в зависимости от их текущего плана.

<Tabs>
  <TabItem label="Liquid-шаблон">

```

{% if Subscription == 'Basic' %}
    Перейдите на Silver, чтобы получить больше функций продукта и поддержку 24/7.
{% elsif Subscription == 'Silver' %}
    Перейдите на Gold для приоритетной поддержки и расширенных функций.
{% else %}
    Пожалуйста, свяжитесь с вашим менеджером, чтобы продлить подписку.
{% endif %}

````

</TabItem>

<TabItem label="API-запрос">

```json
{
  "request": {
    "application": "XXXXX-XXXXX", // Код приложения Pushwoosh
    "auth": "yxoPUlw.....IyEX4H", // Токен доступа API из панели управления Pushwoosh
    "notifications" : [ // параметры пуш-уведомления
      {
       "content": "{% raw %}
{% if Subscription == 'Basic' %}Перейдите на Silver, чтобы получить больше функций продукта и поддержку 24/7.{% elsif Subscription == 'Silver' %}Перейдите на Gold для приоритетной поддержки и расширенных функций.{% else %}Пожалуйста, свяжитесь с вашим менеджером, чтобы продлить подписку. {% endif %}
{% endraw %}",
        "template_bindings": { // опционально. Если в запросе не переданы template_bindings, используются значения тегов с устройства.
         "language" : "es"
        }
      }
    ]
  }
}
````

  </TabItem>

  <TabItem label="Результат">

**Для пользователей с планом подписки Basic:**
Перейдите на Silver, чтобы получить больше функций продукта и поддержку 24/7.

**Для пользователей с планом подписки Silver:**
Перейдите на Gold для приоритетной поддержки и расширенных функций.

**Для пользователей с другими планами:**
Пожалуйста, свяжитесь с вашим менеджером, чтобы продлить подписку.

  </TabItem>
</Tabs>


### Теги-списки

Шаблоны контента очень полезны для обработки тегов типа List.

#### Размер переменной

Один из возможных вариантов использования — доставка разного контента в зависимости от количества значений, содержащихся в теге. Например, вы можете предоставлять разные скидки клиентам с разным поведением. Допустим, у клиента есть несколько товаров в списке желаний — поощрите его к покупке с наиболее подходящей скидкой в зависимости от того, сколько товаров он собирается купить!


<Tabs>
<TabItem label="Liquid-шаблон">

```

{% if WishList.size >= 3 %}
Получите скидку 20% на следующую покупку!
{% elsif WishList.size == 2 %}
Получите скидку 10% на следующую покупку!
{% else %}
Эй, взгляните на новую верхнюю одежду!
{% endif %}

````

</TabItem>

<TabItem label="API-запрос">

```javascript
{
  "request": {
    "application": "XXXXX-XXXXX", // Код приложения Pushwoosh
    "auth": "yxoPUlw.....IyEX4H", // Токен доступа API из панели управления Pushwoosh
    "notifications" : [ // параметры пуш-уведомления
      {
       "content": "{% raw %}
{% if WishList.size >= 3 %}Получите скидку 20% на следующую покупку!{% elsif WishList.size == 2 %}Получите скидку 10% на следующую покупку!{% else %}Эй, взгляните на новую верхнюю одежду!{% endif %}
{% endraw %}",
        "template_bindings": {
         "WishList" : ["Skinny Low Ankle Jeans", "Linen Trenchcoat", "High Waisted Denim Skirt", "Strappy Tiered Maxi Dress"]
        }
      }
    ]
  }
}
````

</TabItem>

<TabItem label="Размер WishList ≥ 3">

<img src="/personalization-liquid-templates-1.webp" alt="Предпросмотр email с размером списка желаний больше или равным 3" width="200"/>

</TabItem>

<TabItem label="Размер WishList = 2">

<img src="/personalization-liquid-templates-2.webp" alt="Предпросмотр email с размером списка желаний равным 2" width="200"/>

</TabItem>
</Tabs>

#### Переменная содержит

Еще один случай, который вам может понадобиться, — это работа со значениями тегов-списков и доставка наиболее релевантного контента в зависимости от того, какие значения содержит тег.

<Tabs>
<TabItem label="Liquid-шаблон">

```

{% if WishList contains 'Skinny Low Ankle Jeans' %}
Получите скидку 20% на товары из вашего списка желаний!
{% else %}
Эй, взгляните на совершенно новые Skinny Low Ankle Jeans!
{% endif %}

````

</TabItem>

<TabItem label="API-запрос">

```javascript
{
  "request": {
    "application": "C90C0-0E786",
    "auth": "yxoPUlw.....IyEX4H", // Токен доступа API из панели управления Pushwoosh
    "notifications" : [ // параметры пуш-уведомления
      {
       "content": "{% raw %}
{% if WishList contains 'Skinny Low Ankle Jeans' %}Получите скидку 20% на следующую покупку!{% else %}Эй, взгляните на совершенно новые Skinny Low Ankle Jeans!{% endif %}
{% endraw %}",
        "template_bindings": {
         "WishList" : ["Skinny Low Ankle Jeans", "Linen Trenchcoat", "High Waisted Denim Skirt", "Strappy Tiered Maxi Dress"]
        }
      }
    ]
  }
}
````

</TabItem>

<TabItem label="Переменная содержит данные">

<img src="/personalization-liquid-templates-3.webp" alt="Персонализированный шаблон с данными" width="200"/>

</TabItem>

<TabItem label="Переменная не содержит данные">

<img src="/personalization-liquid-templates-4.webp" alt="Резервный вид при отсутствии данных" width="200"/>

</TabItem>
</Tabs>


### Множественное число

Используя шаблоны контента, вы можете настраивать контент сообщения в соответствии с поведением пользователей. Например, вы можете изменять текст сообщения, чтобы он содержал слова во множественном числе, если тег-список содержит более одного значения.


<Tabs>
<TabItem label="Liquid-шаблон">

```
    Получите скидку 20% на товар
{% if WishList.size > 1 %}
    ы в вашем WishList!
{% else %}
     в вашем Wishlist!
{% endif %}

````

</TabItem>

<TabItem label="API-запрос">

```javascript
{
  "request": {
    "application": "C90C0-0E786",
    "auth": "yxoPUlw.....IyEX4H", // Токен доступа API из панели управления Pushwoosh
    "notifications" : [ // параметры пуш-уведомления
      {
       "content": "Получите скидку 20% на товар{% raw %}
{% if WishList.size > 1 %}ы в вашем WishList!{% else %} в вашем Wishlist!{% endif %}
{% endraw %}",
        "template_bindings": { // опционально. Если в запросе не переданы template_bindings, используются значения тегов с устройства.
         "WishList" : ["Skinny Low Ankle Jeans", "Linen Trenchcoat", "High Waisted Denim Skirt", "Strappy Tiered Maxi Dress"]
        }
      }
    ]
  }
}
````

</TabItem>

<TabItem label="Множественное число">

<img src="/personalization-liquid-templates-5.webp" alt="Пример шаблона для множественного числа" width="200"/>

</TabItem>

<TabItem label="Единственное число">

<img src="/personalization-liquid-templates-6.webp" alt="Пример шаблона для единственного числа" width="200"/>

</TabItem>
</Tabs>

### Часовой пояс

Шаблон для часовых поясов преобразует дату и время в соответствии с указанным часовым поясом.

<Tabs>
<TabItem label="Liquid-шаблон">
```
{{ MyDate | timezone: MyTimezone | date: \"%Y-%m-%d %H:%M\" }}
```
</TabItem>

<TabItem label="API-запрос">
```javascript title="Пример"
{
  "request" : {
    "auth" : "3H9bk8w3.....Acge2RbupTB", // Токен доступа API из панели управления Pushwoosh
    "application" : "XXXXX-XXXXX", // Код приложения Pushwoosh
    "notifications" : [ // параметры пуш-уведомления
      {
        "content": "Текущая дата: {{ MyDate | timezone: MyTimezone | date: \"%Y-%m-%d %H:%M\" }}",
        "template_bindings": { // опционально. Если в запросе не переданы template_bindings, используются значения тегов с устройства.
         "MyDate" : "2019-07-23 15:00",
         "MyTimezone" : "Asia/Dubai"
        }
      }
    ]
  }
}
```
</TabItem>
<TabItem label="Результат"> <img src="/personalization-liquid-templates-7.webp" alt="Персонализированный вывод даты в пуш-уведомлении" width="200"/>
</TabItem>
</Tabs>


## Связанный контент

Связанный контент — это функция в Liquid-шаблонах, которая позволяет динамически извлекать и использовать данные из внешнего источника, такого как веб-сервис, непосредственно в ваших email-сообщениях или пуш-уведомлениях. Эта функция обеспечивает персонализацию в реальном времени, извлекая JSON-данные по указанному URL и сохраняя их в переменную, которую можно использовать в вашем контенте.

#### Основные сценарии использования

- **Рекомендации продуктов**: отображение персонализированных списков продуктов, адаптированных для каждого пользователя.

- **Промокоды**: вставка уникальных промокодов, сгенерированных бэкенд-сервисом.

#### Предварительные условия

* Для использования связанного контента у вас должен быть собственный бэкенд-сервис, который генерирует и предоставляет необходимые данные (например, промокоды, рекомендации продуктов) на основе **User ID, HWID или пользовательских тегов**. Затем Pushwoosh извлекает эти данные перед отправкой сообщения.

### Пошаговое руководство по внедрению


#### Шаг 1. Настройте бэкенд-сервис

Бэкенд-сервис должен:

* Принимать запрос, содержащий параметры, специфичные для пользователя (например, `userId`). Связанный контент поддерживает `UserID`, `HWID` или любые пользовательские теги, которые вы настроили в своем проекте.
* Возвращать JSON-ответ с необходимыми данными. Этот контент затем можно динамически вставлять в сообщения.

<Aside type="note" title="Как это работает">

Бэкенд-сервис выступает в качестве поставщика данных, отвечая на HTTP-запросы информацией, специфичной для пользователя.

1. Pushwoosh отправляет запрос на ваш бэкенд, передавая идентификаторы, специфичные для пользователя, в качестве параметров запроса.
2. Ваш бэкенд обрабатывает запрос и извлекает запрошенные данные.
3. Ваш бэкенд возвращает JSON-ответ.
4. Перед отправкой сообщения Pushwoosh извлекает JSON-ответ от бэкенд-сервиса и динамически использует возвращенные значения (например, `code`) в контенте сообщения.

**Пример ответа**

```
{ "code": "SPECIALOFFERFORUSER12345" }
```
</Aside>



#### Шаг 2. Создайте пресет со связанным контентом в Pushwoosh

1. В редакторе контента [пушей](/ru/product/content/push-presets/) или [email](/ru/product/content/email-content/drag-and-drop-email-editor/) вставьте синтаксис связанного контента в поле сообщения.

**Пример**

```
{% connected_content http://your-backend-url.com?userId={{ ${userid} }} :save result %}
```
**Разбор синтаксиса**
|  |  |
| ----- | ----- |
| `connected_content` | Извлекает JSON-данные с указанного URL бэкенда. |
|    `http://your-backend-url.com` | Конечная точка бэкенда, которая возвращает необходимые данные в формате JSON. |
| `userId={{ ${userid} }}` | Динамический параметр запроса, который передает ID пользователя на бэкенд. |
| `:save result` | Сохраняет полученный JSON-ответ в переменную `result` для использования в Liquid-шаблонах. |

![Вставьте синтаксис связанного контента](/connectedcontent.webp)

**Аутентификация (опционально)**

Если ваш бэкенд-сервис требует аутентификации, вы можете включить API-ключ или токен в запрос связанного контента для обеспечения безопасного доступа.

```
{% connected_content http://your-backend-url.com?userId={{ ${userid} }}&auth=YOUR_API_KEY :save result %}
```

Вы также можете отправлять данные аутентификации (или любые другие) в виде HTTP-заголовков, используя опциональный параметр `:headers` — JSON-объект с именами и значениями заголовков.

```
{% connected_content http://your-backend-url.com?userId={{ ${userid} }} :headers {"Authorization": "Bearer YOUR_TOKEN", "X-Api-Key": "YOUR_API_KEY"} :save result %}
```
|  |  |
| ----- | ----- |
| `:headers {...}` | JSON-объект HTTP-заголовков, отправляемых с запросом, например, `Authorization: Bearer <token>`. |

<Aside type="caution" title="Только статические значения">
Переменные персонализации `${}` работают только внутри URL. Значения внутри `:headers` являются статическими и не интерполируются.
</Aside>

<Aside type="danger" title="Не храните учетные данные в URL">
Предпочитайте `:headers` параметру запроса URL (например, `&auth=YOUR_API_KEY`) для API-ключей и токенов: если запрос не удастся, URL запроса будет записан в логи, что приведет к раскрытию ключа, размещенного там. Значения внутри `:headers` никогда не логируются.

Связанный контент также требует, чтобы для вашей учетной записи были включены Liquid-шаблоны. Если они не включены, весь тег `connected_content` — включая любой ключ внутри него — будет отправлен каждому получателю как обычный текст вместо того, чтобы быть обработанным. Свяжитесь со [службой поддержки Pushwoosh](https://help.pushwoosh.com/hc/en-us/requests/new), если вы не уверены, включена ли эта функция для вашей учетной записи.
</Aside>

**Использование тегов в связанном контенте**

Чтобы включить пользовательские теги, вставьте их в качестве параметров запроса в запрос **связанного контента** (`{{ tag_name }}`).

```
{% connected_content http://your-backend-url.com?userId={{ ${userid} }}{{ Language }} :save result %}
```

2. Затем добавьте текст сообщения, включающий **полученные данные**, например:

```

Привет, {{userid}}, получите ваш персональный промокод - {{result.code}}
```

![Добавьте текст сообщения с полученными данными](/connectedcontent-1.webp)

3. После завершения работы с контентом сообщения и настройки параметров пресета сохраните его для повторного использования в кампаниях.

<video src="/connectedcontent-2.webm" title="Отправка сообщения со связанным контентом" autoplay loop muted playsinline />

#### Шаг 3. Отправьте сообщение, используя настроенный пресет

Отправьте сообщение с этим пресетом, используя форму [разового пуша](/ru/product/messaging-channels/push-notifications/send-push-notifications/one-time-push/#how-to-send-a-push-notification-using-the-one-time-push-form) или [email](/ru/product/messaging-channels/emails/send-email/#how-to-send-a-one-time-email), или [customer journey](/ru/product/customer-journey/pushwoosh-journey-overview/).

<Aside type="caution" title="Важно">
Если сервис вернет статус, отличный от HTTP 200 OK, email или пуш-уведомление не будет отправлено. Это гарантирует, что ваше сообщение будет отправлено только в том случае, если необходимые данные будут успешно получены.
</Aside>