Smartcat Template Engine

С помощью технологии Smartcat Template Engine вы можете создать собственные шаблоны, по которым будут формироваться нужные вам документы. Например, вы можете создать индивидуальные бланки счетов и смет, которые вы выставляете клиентам.

Как это работает

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

Модель данных — это набор полей, содержащих информацию об элементах модели. Для примера возьмём модель, с помощь которой будут генерироваться документ с информацией о выполненной работе.  У модели будут такие поля:

Название поля

Описание

Name

Наименование работы

Price

Цена с учётом налога

Words

Количество переведённых слов

Date

Дата завершения работы

Executive.FirstName

Имя исполнителя

Executive.LastName

Фамилия исполнителя

Executive.Price

Ставка исполнителя за слово

 

Шаблон содержит текст и специальные теги, используемые для вывода или подстановки данных из модели. Для вывода нужного поля используйте конструкцию <<[Field1]>>, где Field1 — название поля.

Пример шаблона для вывода информации о выполненной работе:

Шаблон

Результат

Проект: <<[Name]>>

Дата сдачи: <<[Date]>>

Исполнитель: <<[Executive.FirstName + “ ” + Executive.LastName]>>

Ставка исполнителя: <<[Executive.Price * Words]>>

Проект: PRESS_RELEASE_APR2020

Дата сдачи: 22.04.2020

Исполнитель: Артём Филатов

Ставка исполнителя: 0.44

 

В шаблоне можно использовать арифметические операции — сложение (+), вычитание (–), умножение (*) и деление (/). Их можно применять к содержимому числовых полей модели, таким как цена или количество перевёденных слов. Содержимое строковых полей, таких как имя исполнителя, можно выводить одно за другим, а также вместе с произвольными строками. В примере выше из имени и фамилии формируется полное имя исполнителя.

 

Продвинутые функции

 

Циклы

Чтобы вывести массивы данных, можно использовать циклы. Цикл выглядит так:

<<foreach [item in Items]>>
<<[item]>>
<</foreach>>

Здесь Items — массив данных, item — элемент из массива, а [item] — вывод значения элемента.

Примеры  циклов

Скажем, в массиве Items лежат строковые значения item1, item2 и item3. Шаблон и результат будут такими:

Шаблон

Результат

<<foreach [item in items]>>

<<[item]>>

<</foreach>>

item1

item2

item3

 

Выведем значения в виде нумерованного списка:

Шаблон

Результат

1. <<foreach [item in items]>>

<<[item]>>

<</foreach>>

  1. item1
  2. item2
  3. item3


Вывод данных в таблицах с помощью циклов

Скажем, у нас есть модель данных Contracts со списком договоров. Каждый договор содержит информацию о стоимости, клиенте и менеджере. Описание полей модели Contract:

Название поля

Описание

Clients.Name

Название компании клиента

Price

Стоимость в договоре

Managers.Name

Имя менеджера

 

Создадим на основе этой модели шаблон:

Клиент

Менеджер

Стоимость в договоре

<<foreach [

    c in Contracts

]>><<[c.Clients.Name]>>

<<[c.Managers.Name]>>

<<[c.Price]>><</foreach>>

Total:

<<[Contracts.Sum(c => c.Price)]>>

 

Результат:

Клиент

Менеджер

Стоимость в договоре

A Company

John Smith

1200000

B Ltd.

John Smith

750000

C & D

John Smith

350000

E Corp.

Tony Anderson

650000

F & Partners

Tony Anderson

550000

G & Co.

July James

350000

H Group

July James

250000

I & Sons

July James

100000

J Ent.

July James

100000

Total:

4300000

 

Немного изменим модель данных. Теперь у нас есть список менеджеров, у каждого менеджера — список договоров, у каждого договора — клиент.

 

Шаблон:

Менеджер/Клиент

Стоимость в договоре

<<foreach [

    m in Managers

]>><<[m.Name]>>

<<[m.Contracts.Sum(c => c.Price)]>>

<<foreach [

    c in m.Contracts

]>>  <<[c.Clients.Name]>>

<<[c.Price]>><</foreach>><</foreach>>

Total:

<<[Contracts.Sum(c => c.Price)]>>

 

Результат:

Менеджер/Клиент

Стоимость в договоре

John Smith

2300000

 A Company

1200000

 B Ltd.

750000

 C & D

350000

Tony Anderson

1200000

 E Corp.

650000

 F & Partners

550000

July James

800000

 G & Co.

350000

 H Group

250000

 I & Sons

100000

 J Ent.

100000

Total:

4300000

 

Перечислим клиентов для каждого менеджера.

Шаблон:

Менеджер

Клиенты

<<foreach [

    m in Managers

]>><<[m.Name]>>

<<foreach [
    c in m.Contracts
]>><<[c.Clients.Name]>>

<</foreach>><</foreach>>

Результат:

Менеджер

Клиенты

John Smith

A Company

B Ltd.

C & D

Tony Anderson

E Corp.

F & Partners

July James

G & Co.

H Group

I & Sons

J Ent.

 

Создадим шаблон для вывода таблицы с одной колонкой, используя опцию “-greedy”.

 

Шаблон:

Менеджеры

<<foreach [m in ds.Managers]>><<[m.Name]>><</foreach -greedy>>

 

 Результат:

Менеджеры

John Smith

Tony Anderson

July James

 

Условные операторы

 

Чтобы вывести ту или иную информацию в зависимости от описанных условий, используйте условные операторы:

<<if [conditional_expression1]>>
template_option1
<<elseif [conditional_expression2]>>
template_option2
...
<<else>>
default_template_option
<</if>>

Здесь conditional_expression — проверка условия, возвращающее одно из двух значений: “true” («правда») или “false” («ложь»).

 Скажем, у нас есть модель данных с массивом Items, в котором лежат строковые значения item1, item2 и item3, Создадим шаблон, который проверит, есть ли элементы в массиве ([!items.Any()]). Если есть, шаблон выведет количество элементов, иначе — сообщение no items.

Шаблон

Результат

You have chosen <<if [!items.Any()]>>no items<<else>><<[items.Count()]>> item(s)<</if>>.

You have chosen 3 item(s).

 

Используя функцию IndexOf(), выделим чётные элементы жёлтым:

Шаблон

Результат

<<foreach [item in items]>><<if [IndexOf() % 2 == 0]>><<[item]>>
<<else>><<[item]>>
<</if>><</foreach>>

item1
item2
item3

 

Выведем все элементы массива, а если их нет — сообщение No data.

<<if [!items.Any()]>>No data.
<<else>><<foreach [item in items]>><<[item]>>
<</foreach>><</if>>

 

Таблицы и условные операторы

 

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

<<if ...>> ...

...

...

...

...

...

<<elseif ...>> ...

...

...

...

...

...

<<else>> ...

...

...

...

...

...

...

...

... <</if>>

 

 

 

 

 

Рассмотрим в качестве модели данных список клиентов. Описание полей модели Client:

Название поля

Описание

Name

Наименование 

Country

Страна

LocalAddress

Адрес

 

Рассмотрим шаблон, который выводит данные по всем клиентам в таблицу. Клиенты из Новой Зеландии (“New Zealand”) будут выделены зёленым, относящиеся к ним столбцы будут объединены, а из полей будет выведено только поле “LocalAddress”.

...

...

...

<<foreach [in clients]>><<if [Country == “New Zealand”]>><<[Name]>>

<<[LocalAddress]>>

<<else>><<[Name]>>

<<[Country]>>

<<[LocalAddress]>><</if>><</foreach>>

...

...

...

 

Результат:

A Company

Australia

219-241 Cleveland St

STRAWBERRY HILLS  NSW  1427

B Ltd.

Brazil

Avenida João Jorge, 112, ap. 31

Vila Industrial

Campinas — SP

13035-680

C & D

Canada

101-3485 RUE DE LA MONTAGNE

MONTRÉAL (QUÉBEC) H3G 2A6

E Corp.

445 Mount Eden Road

Mount Eden

Auckland 1024

F & Partners

20 Greens Road

Tuahiwi

Kaiapoi 7691

G & Co.

Greece

Karkisias 6

GR-111 42  ATHINA

GRÉCE

H Group

Hungary

Budapest

Fiktív utca 82., IV. em./28.

2806

I & Sons

43 Vogel Street

Roslyn

Palmerston North 4414

 

 

Ниже — шаблон, который выдаст соответствующее сообщение, если данных нет:

Клиент

Страна

Адрес

<<if [!clients.Any()]>>No data

<<else>><<foreach [in clients]>><<[Name]>>

<<[Country]>>

<<[LocalAddress]>><</foreach>><</if>>

 

Результат:

Client

Country

Local Address

No data

 

Шаблон:

Шаблон

Результат


Header

<<if [false]>>Content to remove<</if>>

Footer


Header

Footer

 

Применим опцию “-greedy” к шаблону выше:

Шаблон

Результат


Header

<<if [false]>>Content to remove<</if -greedy>>

Footer


Header

Footer

 

Вспомогательные методы для работы с массивами

 

Технология Smartcat Template Engine позволяет гибко работать с массивами данных, используя вспомогательные методы (методы расширения).

 

Скажем, у нас есть модель данных, содержащая поле persons — список сотрудников.

Описание полей модели Person (информация о сотруднике):

Название поля

Описание

Name 

Имя сотрудника

Age 

Возраст сотрудника

Subordinates

Список подчинённых сотрудников

Salary

Зарплата сотрудника

 

Создадим шаблон для вывода имен сотрудников старше 50 лет:

Шаблон

Результат

<<foreach [person in persons.All(p => p.Age > 50)]>>

<<[person.Name]>>

<</foreach>>

Иван Петров

Андрей Козлов

Виктор Кошкин

 

А теперь выведем сумму зарплат всех сотрудников:

Шаблон

Результат

<<[persons.Sum( p => p.Salary)]>>

490000

 

В таблице ниже приведено описание всех доступных методов. В качестве примера используется модель данных с двумя массивами: persons и otherPersons. Оба содержат информацию о сотрудниках.

Функция

Пример

All(Predicate) 

persons.All(p => p.Age < 50) 

Any() 

persons.Any() 

Average(Selector) 

persons.Average(p => p.Age)

Concat(IEnumerable) 

persons.Concat(otherPersons) 

Contains(Object) 

persons.Contains(otherPersons.First()) 

Count() 

persons.Count() 

Count(Predicate) 

persons.Count(p => p.Age > 30) 

Distinct() 

persons.Distinct() 

First() 

persons.First() 

First(Predicate) 

persons.First(p => p.Age > 30) 

FirstOrDefault() 

persons.FirstOrDefault() 

FirstOrDefault(Predicate) 

persons.FirstOrDefault(p => p.Age > 30) 

GroupBy(Selector) 

persons.GroupBy(p => p.Age) 

Or

persons.GroupBy(

    p => new

    {

        Age = p.Age,

        Count = p.Children.Count()

    })

Last() 

persons.Last() 

Last(Predicate) 

persons.Last(p => p.Age > 100) 

LastOrDefault() 

persons.LastOrDefault() 

LastOrDefault(Predicate) 

persons.LastOrDefault(p => p.Age > 100) 

Max(ComparableSelector) 

persons.Max(p => p.Age) 

Min(ComparableSelector) 

persons.Min(p => p.Age) 

OrderBy(ComparableSelector) 

persons.OrderBy(p => p.Age)

Or

persons.OrderBy(p => p.Age)

    .ThenByDescending(p => p.Name)

Or

persons.OrderBy(p => p.Age)

    .ThenByDescending(p => p.Name)

    .ThenBy(p => p.Children.Count())

OrderByDescending(ComparableSelector) 

persons.OrderByDescending(p => p.Age)

Or

persons.OrderByDescending(p => p.Age)

    .ThenByDescending(p => p.Name)

Or

persons.OrderByDescending(p => p.Age)

    .ThenByDescending(p => p.Name)

    .ThenBy(p => p.Children.Count())

Single() 

persons.Single() 

Single(Predicate) 

persons.Single(

    p => p.Name == "John Smith")

SingleOrDefault() 

persons.SingleOrDefault() 

SingleOrDefault(Predicate) 

persons.SingleOrDefault(

    p => p.Name == "John Smith")

Skip(int) 

persons.Skip(10) 

SkipWhile(Predicate) 

persons.SkipWhile(p => p.Age < 21) 

Sum(Selector) 

persons.Sum(p => p.Children.Count())

Take(int) 

persons.Take(5) 

TakeWhile(Predicate) 

persons.TakeWhile(p => p.Age < 50) 

Union(IEnumerable) 

persons.Union(otherPersons)

Where(Predicate) 

persons.Where(p => p.Age > 18) 

 

Информация для разработчиков

Smartcat Template Engine использует подмножество языка C# (C# Language Specification 5.0) в синтаксисе шаблона. Для всех примитивных типов можно использовать методы из BCL, например для строк. Методы, описанные в параграфе «Вспомогательные методы для работы с массивами» — это методы расширения для языка запросов LINQ.

Понравилось?

16

Похожие статьи:

    Нет похожих статей