Учебник Thymeleaf: Глава 13. Текстовые режимы шаблона
13 Текстовые режимы шаблона
13.1 Текстовый синтаксис
Три типа шаблонов Thymeleaf считаются текстовыми: TEXT, JAVASCRIPT и CSS. Это отличает их от режимов шаблонов разметки: HTML и XML.
Ключевое различие между режимами текстового шаблона и разметкой заключается в том, что в текстовом шаблоне нет тегов, в которые нужно вставлять логику в виде атрибутов, поэтому мы должны полагаться на другие механизмы.
Первый и самый основной из этих механизмов — это вложение, о чем мы уже говорили в предыдущей главе. Inlining синтаксис — самый простой способ вывода результатов выражений в режиме текстового шаблона.
Рассмотрим письмо:
Dear [(${name})], Please find attached the results of the report you requested with name "[(${report.name})]". Sincerely, The Reporter.
Даже без тегов вышеприведенный пример представляет собой полный и действительный шаблон Thymeleaf, который может быть выполнен в режиме TEXT.
Но для того, чтобы включить более сложную логику, чем простые выражения, нам нужен новый синтаксис, не содержащий тегов:
[# th:each="item : ${items}"] - [(${item})] [/]
На самом деле это сокращенная версия более подробного варианта:
[#th:block th:each="item : ${items}"] - [#th:block th:utext="${item}" /] [/th:block]
Обратите внимание, как этот новый синтаксис основан на элементах (т. е. обрабатываемых тегах), которые объявляются как [#element …] вместо <element …>. Элементы открыты как [#element …] и закрыты как [/element], а автономные теги могут быть объявлены путем сведения к минимуму открытого элемента с помощью / способом, почти эквивалентным XML-тегам: [#element… /].
Стандартный диалект содержит только процессор для одного из этих элементов: уже известного th:block, хотя мы могли бы расширять наши диалекты и создавать новые элементы обычным способом. Кроме того, элемент th:block ([#th:block …]… [/th:block]) разрешено сокращать как пустую строку ([# …]… [/]), поэтому приведенный выше блок фактически эквивалентен:
[# th:each="item : ${items}"] - [# th:utext="${item}" /] [/]
И данный [# th:utext=»${item}» /] эквивалентен встроенному неэкранированному выражению, мы могли бы просто использовать его, чтобы иметь меньше кода. Таким образом, мы получаем первый фрагмент кода, который мы видели выше:
[# th:each="item : ${items}"] - [(${item})] [/]
Обратите внимание, что текстовый синтаксис требует полного баланса элементов (отсутствия незакрытых тегов) и цитируемых атрибутов — это скорее стиль XML, чем стиль HTML.
Давайте рассмотрим более полный пример шаблона TEXT, шаблон текстового электронного письма:
Dear [(${customer.name})], This is the list of our products: [# th:each="prod : ${products}"] - [(${prod.name})]. Price: [(${prod.price})] EUR/kg [/] Thanks, The Thymeleaf Shop
После выполнения, результатом может быть что-то вроде:
Dear Mary Ann Blueberry, This is the list of our products: - Apricots. Price: 1.12 EUR/kg - Bananas. Price: 1.78 EUR/kg - Apples. Price: 0.85 EUR/kg - Watermelon. Price: 1.91 EUR/kg Thanks, The Thymeleaf Shop
И еще один пример в режиме шаблона JAVASCRIPT, файл greeter.js, мы обрабатываем как текстовый шаблон, и который вызываем на HTML-страницах. Обратите внимание, что это не блок <script> в HTML-шаблоне, а файл .js обрабатывается как шаблон самостоятельно:
var greeter = function() { var username = [[${session.user.name}]]; [# th:each="salut : ${salutations}"] alert([[${salut}]] + " " + username); [/] };
После выполнения, результатом этого может быть что-то вроде:
var greeter = function() { var username = "Bertrand \"Crunchy\" Pear"; alert("Hello" + " " + username); alert("Ol\u00E1" + " " + username); alert("Hola" + " " + username); };
Экранированные атрибуты элемента
Чтобы избежать взаимодействия с частями шаблона, которые могут быть обработаны в других режимах (например, в текстовом режиме, встраиваемом внутри HTML-шаблона), Thymeleaf 3.0 позволяет избегать атрибуты элементов в его текстовом синтаксисе. Так:
- Атрибуты в режиме шаблона TEXT будут неэкранированы HTML
- Атрибуты в режиме шаблона JAVASCRIPT будут JavaScript-unescaped
- Атрибуты в режиме шаблона CSS будут CSS-unescaped
Так что это было бы отлично в шаблоне TEXT (обратите внимание на >):
[# th:if="${120<user.age}"] Congratulations! [/]
Конечно, в реальном текстовом шаблоне пример не имеет большого смысла, но это хорошая идея, если мы обрабатываем HTML-шаблон с блоком th:inline=«text», содержащим код выше, и мы хотим убедиться, что наш браузер не принимает <user.age для имени открытого тега при статическом открытии файла в качестве прототипа.
13.2 Расширяемость
Одним из преимуществ этого синтаксиса является то, что он столь же расширяем, как и разметка. Разработчики могут по-прежнему определять свои диалекты с помощью настраиваемых элементов и атрибутов, применять к ним префикс (необязательно), а затем использовать их в режимах текстового шаблона:
[#myorg:dosomething myorg:importantattr="211"]some text[/myorg:dosomething]
13.3 Текстовые блоки комментариев только для прототипа: добавление кода
Режимы шаблона JAVASCRIPT и CSS (недоступно для TEXT) позволяют включать код между специальным синтаксисом комментария /*[+…+]*/, чтобы Thymeleaf автоматически раскомментировал такой код при обработке шаблона:
var x = 23; /*[+ var msg = "This is a working application"; +]*/ var f = function() { ...
Будет выполнено как:
var x = 23; var msg = "This is a working application"; var f = function() { ...
Вы можете включать выражения внутри этих комментариев, и они будут оцениваться:
var x = 23; /*[+ var msg = "Hello, " + [[${session.user.name}]]; +]*/ var f = function() { ...
13.4 Текстовые блоки комментариев на уровне парсера: удаление кода
Подобным образом, как и для блоков комментариев для прототипа, все три режима текстовых шаблонов (TEXT, JAVASCRIPT и CSS) позволяют инструктировать Thymeleaf для удаления кода между специальными /*[- */ и /* -]*/ маркерами:
var x = 23; /*[- */ var msg = "This is shown only when executed statically!"; /* -]*/ var f = function() { ...
Или в TEXT режиме:
... /*[- Note the user is obtained from the session, which must exist -]*/ Welcome [(${session.user.name})]! ...
13.5 Естественные шаблоны JavaScript и CSS
Как видно из предыдущей главы, JavaScript и CSS-inlining предлагают возможность включать встроенные выражения в комментарии JavaScript / CSS, например:
... var username = /*[[${session.user.name}]]*/ "Sebastian Lychee"; ...
… который является действительным JavaScript, и исполняемый код может выглядеть так:
... var username = "John Apricot"; ...
Этот же трюк включения встроенных выражений внутри комментариев может фактически использоваться для всего синтаксиса текстового режима:
/*[# th:if="${user.admin}"]*/ alert('Welcome admin'); /*[/]*/
Это предупреждение в приведенном выше коде будет показано, когда шаблон открыт статически, потому что он на 100% JavaScript, а также когда шаблон запускается, если пользователь является администратором. Это эквивалентно:
[# th:if="${user.admin}"] alert('Welcome admin'); [/]
… который на самом деле является кодом, который преобразует исходная версия во время разбора шаблонов.
Обратите внимание, однако, что обертывание элементов в комментариях не очищает строки, в которых они живут (справа до тех пор, пока ; не будет найдено), как это делают inlined выражения. Это поведение зарезервировано только для inlined выражений.
Таким образом, Thymeleaf 3.0 позволяет создавать сложные JavaScript-скрипты и таблицы стилей CSS в виде естественных шаблонов, действительных как прототипом, так и рабочим шаблоном.

