# Переменные в Markdown-шаблонах

Дорогие друзья, добро пожаловать в этот tutorial. В этом разделе мы шаг за шагом научимся использовать Markdown и шаблонизатор Handlebars для динамического отображения контента. В материале «Полезности Markdown-блоков» Вы уже познакомились с базовым синтаксисом, способами создания и подстановкой переменных, теперь же погрузимся в продвинутые возможности.

## 1 Знакомство с шаблонизатором [Handlebars](https://docs-cn.nocobase.com/handbook/template-handlebars)

После создания Markdown-блока в правом верхнем углу настроек Вы увидите параметр «Шаблонизатор» — по умолчанию там стоит Handlebars. Handlebars позволяет динамически выводить содержимое страницы по условиям, и Markdown тоже становится «реагирующим».

![Шаблонизатор](https://static-docs.nocobase.com/20250304011925.png)

### 1.1 Зачем Handlebars

Markdown сам по себе поддерживает только статический контент, но через Handlebars можно по условиям (статус, число, опция) переключать тексты и стили. Так страница всегда показывает актуальную информацию даже в меняющихся бизнес-сценариях.

## 2 Практические сценарии

Рассмотрим несколько полезных сценариев и реализуем их шаг за шагом.

### 2.1 Обработка статуса заказа

В онлайн-демо часто нужно показывать разную подсказку в зависимости от статуса заказа. Допустим, в таблице заказов есть поле статуса со следующими значениями:

![Поле статуса](https://static-docs.nocobase.com/20250304091420.png)

Содержимое для 4 статусов:


| Метка опции      | Значение | Содержание                                                             |
| ---------------- | -------- | ---------------------------------------------------------------------- |
| Pending Approval | 1        | Заказ отправлен, ожидает внутренней проверки.                          |
| Pending Payment  | 2        | Ожидаем оплату клиента. Следите за статусом.                            |
| Paid             | 3        | Оплата подтверждена, дальнейшая обработка. Консультант свяжется в течение часа. |
| Rejected         | 4        | Заказ не утверждён. При необходимости пересмотрите и отправьте снова.   |

На странице мы получим значение статуса заказа и динамически выведем нужную информацию. Ниже подробно про синтаксис if, else и else if.

#### 2.1.1 Синтаксис if

С помощью if показываем содержимое при выполнении условия. Например:

```
{{#if условие}}
  <p>Результат</p>
{{/if}}
```

«Условие» использует синтаксис Handlebars (eq, gt, lt и т. д.). Простой пример:

```
{{#if (eq 1 1)}}
  <p>Результат: 1 = 1</p>
{{/if}}
```

См. эффект ниже:

![Пример if 1](https://static-docs.nocobase.com/20250305115416.png)
![Пример if 2](https://static-docs.nocobase.com/20250305115434.png)

#### 2.1.2 Синтаксис else

Если условие не выполнено, можно через else указать альтернативное содержимое:

```
{{#if (eq 1 2)}}
  <p>Результат: 1 = 2</p>
{{else}}
  <p>Результат: 1 ≠ 2</p>
{{/if}}
```

Эффект:

![Пример else](https://static-docs.nocobase.com/20250305115524.png)

#### 2.1.3 Несколько условий

Для нескольких условий используем else if. Пример:

```
{{#if (eq 1 7)}}
  <p>Результат: 1 = 7</p>
{{else if (eq 1 5)}}
  <p>Результат: 1 = 5</p>
{{else if (eq 1 4)}}
  <p>Результат: 1 = 4</p>
{{else}}
  <p>Результат: 1 ≠ 7 ≠ 5 ≠ 3</p>
{{/if}}
```

Эффект:

![Пример нескольких условий](https://static-docs.nocobase.com/20250305115719.png)

### 2.2 Демонстрация результата

После настройки страницы её содержимое будет динамически меняться в зависимости от статуса. Смотрите ниже:

![Динамика статусов заказа](https://static-docs.nocobase.com/202503040942-handlebar1.gif)

Код страницы:

```
{{#if order.status}}
  <div>
    {{#if (eq order.status "1")}}
      <span style="color: orange;">Pending Approval</span>
      <p>Заказ отправлен, ожидает внутренней проверки.</p>
    {{else if (eq order.status "2")}}
      <span style="color: #1890ff;">Pending Payment</span>
      <p>Ожидаем оплату клиента. Следите за статусом.</p>
    {{else if (eq order.status "3")}}
      <span style="color: #52c41a;">Paid</span>
      <p>Оплата подтверждена, дальнейшая обработка. Консультант свяжется в течение часа.</p>
    {{else if (eq order.status "4")}}
      <span style="color: #f5222d;">Rejected</span>
      <p>Заказ не утверждён. При необходимости пересмотрите и отправьте снова.</p>
    {{/if}}
  </div>
{{else}}
  <p class="empty-state">Сейчас нет заказов в обработке.</p>
{{/if}}
```

Попробуйте переключать статус заказа и наблюдать за обновлением страницы — это покажет, верно ли работает Ваш код.

### 2.3 Отображение позиций заказа

Помимо статуса, часто нужно показать состав заказа (список товаров). Сделаем это через each.

#### 2.3.1 Синтаксис each

each используется для перебора списка. Например, для массива [1,2,3]:

```
{{#each список}}
  <p>Результат: {{this}}</p>
  <p>Индекс: {{@index}}</p>
{{/each}}
```

Внутри цикла `{{this}}` — текущий элемент, `{{@index}}` — текущий индекс.

#### 2.3.2 Пример позиций товара

Если нужно показать все товары заказа:

```
{{#each $nRecord.order_items}}
    <p>{{@index}}</p>
    <p>{{this.id}}</p>
    <p>{{this.price}}</p>
    <p>{{this.quantity}}</p>
    <p>{{this.product.name}}</p>
---
{{/each}}
```

Если данные не появляются, убедитесь, что поле «позиции заказа» правильно отображается, иначе система посчитает их неиспользуемыми и не подтянет.
![20250305122543_handlebar_each](https://static-docs.nocobase.com/20250305122543_handlebar_each.gif)

Возможно, Вы заметите, что название товара (product.name) не выводится. Причина та же — нужно явно показать связанный объект товара.
![20250305122543_each2](https://static-docs.nocobase.com/20250305122543_each2.gif)

После того как мы покажем поле, можно через правила связности скрыть его обратно.
![20250305122543_hidden_each](https://static-docs.nocobase.com/20250305122543_hidden_each.gif)

### 2.4 Финальный результат: список товаров заказа

Завершив шаги выше, Вы получите готовый шаблон списка товаров заказа. Полный код:

```
### Список товаров заказа

{{#if $nRecord.order_items}}
  <div class="cart-summary">Итого: {{$nRecord.order_items.length}} позиций, общая сумма: ¥{{$nRecord.total}}</div>
  
  <table>
    <thead>
      <tr>
        <th>№</th>
        <th>Название товара</th>
        <th>Цена</th>
        <th>Кол-во</th>
        <th>Сумма</th>
      </tr>
    </thead>
    <tbody>
      {{#each $nRecord.order_items}}
        <tr style="{{#if this.out_of_stock}}color: red;{{/if}}">
          <td>{{@index}}</td>
          <td>{{this.product.name}}</td>
          <td>¥{{this.price}}</td>
          <td>{{this.quantity}}</td>
          <td>¥{{multiply this.price this.quantity}}</td>
          <td>
            {{#if this.out_of_stock}}
              <span>Нет в наличии</span>
            {{else if this.low_stock}}
              <span style="color:orange;">Заканчивается</span>
            {{/if}}
          </td>
        </tr>
      {{/each}}
    </tbody>
  </table>
{{else}}
  <p>Заказ пуст</p>
{{/if}}
```

Запустив, Вы увидите:

![Список товаров заказа](https://static-docs.nocobase.com/20250305124125.png)

Чтобы лучше показать гибкость Handlebars, мы добавили в детали заказа поля «нет в наличии» (out_of_stock) и «заканчивается» (low_stock):

- При out_of_stock = true показывается «Нет в наличии», строка становится красной.
- При low_stock = true справа выводится «Заканчивается» оранжевым цветом.

![Дополнительный эффект: нет в наличии и заканчивается](https://static-docs.nocobase.com/20250305130258.png)

## 3 Итоги и рекомендации

После этого материала Вы научились использовать Handlebars для динамического рендеринга Markdown-шаблонов: ключевые конструкции if/else, циклы each и т. д. В реальной разработке для более сложной логики рекомендуем сочетать правила связности, вычисляемые поля, workflow или узлы script — это повысит гибкость и расширяемость.

Тренируйтесь и применяйте техники в проектах. Вперёд, к новым возможностям!

---

Если возникнут вопросы, заходите в [сообщество NocoBase](https://forum.nocobase.com) или загляните в [официальную документацию](https://docs-cn.nocobase.com). Удачной работы и успешного проекта!
