Обработка циклов

Циклы используются для повторяющегося рендера данных из массивов или объектов: в шаблоне задаются маркеры начала и конца области цикла. Ниже приведены несколько типовых сценариев.

Итерация по массивам

1. Описание синтаксиса

  • Используйте {d.array[i].property} для текущего элемента цикла и {d.array[i+1].property} для следующего элемента — так задаётся область цикла.
  • Внутри цикла первая строка (часть с [i]) автоматически используется как шаблон повторения; вам достаточно описать пример цикла один раз.

Формат синтаксиса:

{d.arrayName[i].property}
{d.arrayName[i+1].property}

2. Пример: простой цикл по массиву

Данные
{
  "cars": [
    { "brand": "Toyota", "id": 1 },
    { "brand": "Hyundai", "id": 2 },
    { "brand": "BMW",    "id": 3 },
    { "brand": "Peugeot","id": 4 }
  ]
}
Шаблон
Carsid
{d.cars[i].brand}{d.cars[i].id}
{d.cars[i+1].brand}
Результат
Carsid
Toyota1
Hyundai2
BMW3
Peugeot4

3. Пример: вложенный цикл по массиву

Подходит для случаев, когда массив содержит вложенные массивы; уровень вложенности может быть любым.

Данные
[
  {
    "brand": "Toyota",
    "models": [
      { "size": "Prius 4", "power": 125 },
      { "size": "Prius 5", "power": 139 }
    ]
  },
  {
    "brand": "Kia",
    "models": [
      { "size": "EV4", "power": 450 },
      { "size": "EV6", "power": 500 }
    ]
  }
]
Шаблон
{d[i].brand}

Models
{d[i].models[i].size} - {d[i].models[i].power}
{d[i].models[i+1].size}

{d[i+1].brand}
Результат
Toyota

Models
Prius 4 - 125
Prius 5 - 139

Kia

4. Пример: двунаправленный цикл (продвинутая возможность, v4.8.0+)

Двунаправленные циклы позволяют одновременно итерироваться и по строкам, и по столбцам. Это подходит для генерации сравнительных таблиц и других сложных макетов (примечание: сейчас некоторые форматы официально поддерживаются только для шаблонов DOCX, HTML и MD).

Данные
{
  "titles": [
    { "name": "Kia" },
    { "name": "Toyota" },
    { "name": "Hopium" }
  ],
  "cars": [
    { "models": [ "EV3", "Prius 1", "Prototype" ] },
    { "models": [ "EV4", "Prius 2", "" ] },
    { "models": [ "EV6", "Prius 3", "" ] }
  ]
}
Шаблон
{d.titles[i].name}{d.titles[i+1].name}
{d.cars[i].models[i]}{d.cars[i].models[i+1]}
{d.cars[i+1].models[i]}
Результат
KiaToyotaHopium
EV3Prius 1Prototype
EV4Prius 2
EV6Prius 3

5. Пример: доступ к значениям итератора цикла (v4.0.0+)

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

Пример шаблона
{d[i].cars[i].other.wheels[i].tire.subObject:add(.i):add(..i):add(...i)}

Примечание: количество точек указывает уровень индекса (например, .i — текущий уровень, ..i — предыдущий). Сейчас есть проблема с обратным порядком; подробности смотрите в официальной документации.

Итерация по объектам

1. Описание синтаксиса

  • Для свойств объекта используйте .att для имени свойства и .val для значения свойства.
  • При итерации свойства обходятся по одному.

Формат синтаксиса:

{d.objectName[i].att}  // имя свойства
{d.objectName[i].val}  // значение свойства

2. Пример: итерация по свойствам объекта

Данные
{
  "myObject": {
    "paul": "10",
    "jack": "20",
    "bob":  "30"
  }
}
Шаблон
People namePeople age
{d.myObject[i].att}{d.myObject[i].val}
{d.myObject[i+1].att}{d.myObject[i+1].val}
Результат
People namePeople age
paul10
jack20
bob30

Сортировка

С помощью сортировки можно прямо в шаблоне отсортировать данные массива.

1. Описание синтаксиса: сортировка по возрастанию

  • Укажите атрибут как критерий сортировки в теге цикла. Формат синтаксиса:
    {d.array[sortingAttribute, i].property}
    {d.array[sortingAttribute+1, i+1].property}
  • Для нескольких критериев сортировки перечислите атрибуты через запятую внутри скобок.

2. Пример: сортировка по числовому атрибуту

Данные
{
  "cars": [
    { "brand": "Ferrari", "power": 3 },
    { "brand": "Peugeot", "power": 1 },
    { "brand": "BMW",     "power": 2 },
    { "brand": "Lexus",   "power": 1 }
  ]
}
Шаблон
Cars
{d.cars[power, i].brand}
{d.cars[power+1, i+1].brand}
Результат
Cars
Peugeot
Lexus
BMW
Ferrari

3. Пример: сортировка по нескольким атрибутам

Данные
{
  "cars": [
    { "brand": "Ferrari", "power": 3, "sub": { "size": 1 } },
    { "brand": "Aptera",  "power": 1, "sub": { "size": 20 } },
    { "brand": "Peugeot", "power": 1, "sub": { "size": 20 } },
    { "brand": "BMW",     "power": 2, "sub": { "size": 1 } },
    { "brand": "Kia",     "power": 1, "sub": { "size": 10 } }
  ]
}
Шаблон
Cars
{d.cars[power, sub.size, i].brand}
{d.cars[power+1, sub.size+1, i+1].brand}
Результат
Cars
Kia
Aptera
Peugeot
BMW
Ferrari

Фильтрация

Фильтрация используется, чтобы исключать строки в цикле по заданным условиям.

1. Описание синтаксиса: числовая фильтрация

  • Добавьте условия в тег цикла (например, age > 19). Формат синтаксиса:
    {d.array[i, condition].property}

2. Пример: числовая фильтрация

Данные
[
  { "name": "John",   "age": 20 },
  { "name": "Eva",    "age": 18 },
  { "name": "Bob",    "age": 25 },
  { "name": "Charly", "age": 30 }
]
Шаблон
People
{d[i, age > 19, age < 30].name}
{d[i+1, age > 19, age < 30].name}
Результат
People
John
Bob

3. Описание синтаксиса: строковая фильтрация

  • Указывайте строковые условия в одинарных кавычках. Например:
    {d.array[i, type='rocket'].name}

4. Пример: строковая фильтрация

Данные
[
  { "name": "Falcon 9",    "type": "rocket" },
  { "name": "Model S",     "type": "car" },
  { "name": "Model 3",     "type": "car" },
  { "name": "Falcon Heavy","type": "rocket" }
]
Шаблон
People
{d[i, type='rocket'].name}
{d[i+1, type='rocket'].name}
Результат
People
Falcon 9
Falcon Heavy

5. Описание синтаксиса: оставить первые N элементов

  • Можно использовать индекс цикла i, чтобы отфильтровать первые N элементов. Например:
    {d.array[i, i < N].property}

6. Пример: оставить первые два элемента

Данные
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
Шаблон
People
{d[i, i < 2].name}
{d[i+1, i < 2].name}
Результат
People
Falcon 9
Model S

7. Описание синтаксиса: исключить последние N элементов

  • Используйте отрицательную индексацию i, чтобы обращаться к элементам с конца. Например:
    • {d.array[i=-1].property} — возвращает последний элемент.
    • {d.array[i, i!=-1].property} — исключает последний элемент.

8. Пример: исключить последний элемент и последние два элемента

Данные
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
Шаблон
Последний элемент: {d[i=-1].name}

Без последнего элемента:
{d[i, i!=-1].name}
{d[i+1, i!=-1].name}

Без последних двух элементов:
{d[i, i<-2].name}
{d[i+1, i<-2].name}
Результат
Последний элемент: Falcon Heavy

Без последнего элемента:
Falcon 9
Model S
Model 3

Без последних двух элементов:
Falcon 9
Model S

9. Описание синтаксиса: Интеллектуальная фильтрация

  • Используя блоки интеллектуальных условий, вы можете скрыть целую строку на основе сложных условий. Пример формата:
    {d.array[i].property:ifIN('keyword'):drop(row)}

10. Пример: Интеллектуальная фильтрация

Данные
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
Шаблон
People
{d[i].name}
{d[i].name:ifIN('Falcon'):drop(row)}
{d[i+1].name}
Результат
People
Model S
Model 3

(Примечание: Строки, содержащие «Falcon» в шаблоне, удаляются условием интеллектуальной фильтрации.)

Удаление дублей

1. Описание синтаксиса

  • Используя пользовательский итератор, можно получать уникальные (без дублей) элементы по значению свойства. Синтаксис похож на обычный цикл, но дубликаты автоматически игнорируются.

Формат:

{d.array[property].property}
{d.array[property+1].property}

2. Пример: выбор уникальных данных

Данные
[
  { "type": "car",   "brand": "Hyundai" },
  { "type": "plane", "brand": "Airbus" },
  { "type": "plane", "brand": "Boeing" },
  { "type": "car",   "brand": "Toyota" }
]
Шаблон
Vehicles
{d[type].brand}
{d[type+1].brand}
Результат
Vehicles
Hyundai
Airbus