Повторяющиеся разделы

Повторяющийся раздел создаёт по одной копии блока — строки таблицы, слайда или группы абзацев — для каждого элемента коллекции. Раздел заключён в открывающий и закрывающий теги с именем коллекции:

{{#items}} ... {{/items}}

Имя внутри тегов — items, placements, campaigns — это машинное имя поля-коллекции (вложенной сущности или ссылки на несколько записей) типа сущности, к которому привязан шаблон.

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

Точный механизм зависит от формата шаблона.

DOCX — строки таблицы

Шаблоны DOCX поддерживают два способа повторять строки таблицы.

Схема из трёх строк

Это самый наглядный способ. В таблице под повторяющийся раздел отведены три строки:

  1. Строка с одним {{#items}} в первой ячейке (строка открывающего тега).

  2. Строка шаблона с плейсхолдерами для каждого элемента.

  3. Строка с одним {{/items}} в первой ячейке (строка закрывающего тега).

При формировании документа строки открывающего и закрывающего тегов удаляются. Строка шаблона дублируется для каждого элемента коллекции, а плейсхолдеры заполняются данными этого элемента.

Пример — позиции предложения:

Допустим, шаблон привязан к типу сущности Предложение, у которого есть поле вложенной сущности items (машинное имя). У каждого вложенного элемента свои поля — displayName, period, frequency, price, — определённые у вложенного типа сущности (см. вложенные сущности). Эти вложенные машинные имена и есть плейсхолдеры внутри раздела:

Таблица шаблона

{{#items}}

{{displayName}}

{{period}}

{{frequency}}

{{price}}

{{/items}}

Сформированная таблица

Tverskaya 12

March

Daily

45 000

Nevsky 5

March

Daily

38 000

Arbat 3

March

Weekly

12 000

Если в предложении три позиции, в итоговой таблице три строки данных (строк с тегами нет).

Схема из одной строки

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

Таблица шаблона

{{#items}} {{displayName}}

{{period}}

{{frequency}}

{{price}} {{/items}}

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

Какую схему выбрать

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

DOCX — разделы из нескольких абзацев

Вне таблиц повторяющийся раздел охватывает диапазон абзацев. Открывающий тег — отдельный абзац; закрывающий тег — тоже отдельный абзац.

В этом примере шаблон привязан к типу сущности Кампания, у которого поле вложенной сущности placements (машинное имя) содержит элементы с полями displayName, address, startDate и endDate — все это машинные имена, определённые у вложенного типа сущности:

{{#placements}}

Display: {{displayName}}
Location: {{address}}
Period: {{startDate}} -- {{endDate}}

{{/placements}}

Абзацы между тегами копируются для каждого элемента. Сами абзацы с тегами из результата удаляются.

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

XLSX — циклы по строкам

В шаблонах XLSX повторяющийся раздел работает на уровне строк внутри листа. Открывающий тег стоит в ячейке одной строки, закрывающий — в ячейке одной из следующих строк. Строки между ними образуют блок шаблона.

На том же примере с предложением: items — машинное имя поля-коллекции, а displayName, period, price — машинные имена вложенного типа сущности:

Шаблон
A B C

5

{{#items}}

6

{{displayName}}

{{period}}

{{price}}

7

{{/items}}

Результат
A B C

5

Tverskaya 12

March

45 000

6

Nevsky 5

March

38 000

7

Arbat 3

March

12 000

Строки 5 и 7 (строки с тегами) удаляются. Строка 6 дублируется для каждого элемента. Строки ниже раздела сдвигаются вниз, освобождая место для добавленных.

Вложенные коллекции в XLSX

Шаблоны XLSX поддерживают вложенные повторяющиеся разделы. Раздел внутри другого раздела даёт набор строк для каждого элемента внутренней коллекции, повторённый для каждого элемента внешней.

В этом примере у типа сущности есть поле-коллекция campaigns (машинное имя), а у каждой кампании своя вложенная коллекция placements. campaignName — поле кампании; displayName, address и price — поля размещения; каждое имя — машинное имя, определённое у соответствующего типа сущности:

Шаблон
A B C

3

{{#campaigns}}

4

Campaign: {{campaignName}}

5

{{#placements}}

6

{{displayName}}

{{address}}

{{price}}

7

{{/placements}}

8

{{/campaigns}}

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

Формулы и ссылки на строки

Когда строки дублируются, ссылки на ячейки Excel в формулах не корректируются автоматически. Если формула ссылается на ячейку по адресу (например, =SUM(C2:C10)), адрес остаётся таким, как записан в шаблоне.

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

Стили ячеек и формулы копируются в каждую повторённую строку. Как форматирование сохраняется при повторении и другие особенности XLSX, описано в Шаблоны Excel.

PPTX — циклы по слайдам

В шаблонах PPTX повторяющийся раздел работает на уровне слайдов. Открывающий и закрывающий теги стоят на одном слайде — обычно в текстовом поле или фигуре. Этот слайд становится слайдом шаблона.

При формировании документа:

  1. Слайд шаблона клонируется по одному разу для каждого элемента коллекции.

  2. Плейсхолдеры на каждом клонированном слайде заполняются данными соответствующего элемента.

  3. Исходный слайд шаблона удаляется.

Если коллекция пуста, слайд шаблона просто удаляется — пустого слайда не остаётся.

Пример — медиакит с одним слайдом на конструкцию:

Здесь шаблон привязан к типу сущности Медиакит, у которого есть поле-коллекция displays (машинное имя). У каждой конструкции поля address, formatName и impressionsPerDay — машинные имена вложенного типа сущности.

Слайд шаблона содержит:

{{#displays}}
Location: {{address}}
Format: {{formatName}}
Audience: {{impressionsPerDay}} impressions/day
{{/displays}}

Если в данных пять конструкций, в итоговой презентации пять слайдов, и каждый заполнен данными одной конструкции.

Упрощение для единственной коллекции

Если в данных ровно один массив, а шаблон ссылается на коллекцию с другим именем, движок автоматически сопоставляет имя из шаблона с имеющимся массивом. Значит, шаблон, написанный с {{#screens}}, будет работать, даже если ключ в данных — displays, пока нет неоднозначности.

Это автоматическое сопоставление действует, только когда в данных ровно один массив. Если массивов несколько, имя коллекции в шаблоне должно точно совпадать с ключом в данных.

Доступ к внешним полям внутри раздела

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

  • {{$.fieldName}} — обращается к корневому контексту (записи верхнего уровня) при любой глубине вложенности.

  • {{../fieldName}} — обращается к родительскому контексту (на один уровень выше).

Например, чтобы показать номер сделки рядом с каждой позицией в таблице предложения:

Строка шаблона внутри {{#items}}

{{$.dealNumber}}

{{displayName}}

{{price}}

Пустые коллекции

Когда коллекция пуста:

  • Таблицы DOCX: строки шаблона (и строки с тегами) удаляются. Если в таблице нет других строк, сама таблица остаётся пустой, только с заголовками.

  • Абзацы DOCX: абзацы с тегами и все абзацы с содержимым между ними удаляются.

  • XLSX: строки с тегами и строки шаблона удаляются. Строки ниже сдвигаются вверх.

  • PPTX: слайд шаблона удаляется.

Для пустой коллекции ошибка не возникает.