Оглавление
Три типа шаблонов Thymeleaf считаются текстовыми: TEXT, JAVASCRIPT и CSS. Это отличает их от режимов шаблонов разметки: HTML и XML.
Ключевое различие между режимами текстового шаблона и разметкой заключается в том, что в текстовом шаблоне нет тегов, в которые нужно вставлять логику в виде атрибутов, поэтому мы должны полагаться на другие механизмы.
Первый и самый основной из этих механизмов — это вложение, о чем мы уже говорили в предыдущей главе. Inlining синтаксис — самый простой способ вывода результатов выражений в режиме текстового шаблона.
Рассмотрим письмо:
Даже без тегов вышеприведенный пример представляет собой полный и действительный шаблон Thymeleaf, который может быть выполнен в режиме TEXT.
Но для того, чтобы включить более сложную логику, чем простые выражения, нам нужен новый синтаксис, не содержащий тегов:
На самом деле это сокращенная версия более подробного варианта:
Обратите внимание, как этот новый синтаксис основан на элементах (т. е. обрабатываемых тегах), которые объявляются как [#element ...] вместо <element ...>. Элементы открыты как [#element ...] и закрыты как [/element], а автономные теги могут быть объявлены путем сведения к минимуму открытого элемента с помощью / способом, почти эквивалентным XML-тегам: [#element… /].
Стандартный диалект содержит только процессор для одного из этих элементов: уже известного th:block, хотя мы могли бы расширять наши диалекты и создавать новые элементы обычным способом. Кроме того, элемент th:block ([#th:block ...]… [/th:block]) разрешено сокращать как пустую строку ([# ...]… [/]), поэтому приведенный выше блок фактически эквивалентен:
И данный [# th:utext="${item}" /] эквивалентен встроенному неэкранированному выражению, мы могли бы просто использовать его, чтобы иметь меньше кода. Таким образом, мы получаем первый фрагмент кода, который мы видели выше:
Обратите внимание, что текстовый синтаксис требует полного баланса элементов (отсутствия незакрытых тегов) и цитируемых атрибутов — это скорее стиль XML, чем стиль HTML.
Давайте рассмотрим более полный пример шаблона TEXT, шаблон текстового электронного письма:
После выполнения, результатом может быть что-то вроде:
И еще один пример в режиме шаблона JAVASCRIPT, файл greeter.js, мы обрабатываем как текстовый шаблон, и который вызываем на HTML-страницах. Обратите внимание, что это не блок <script> в HTML-шаблоне, а файл .js обрабатывается как шаблон самостоятельно:
После выполнения, результатом этого может быть что-то вроде:
Экранированные атрибуты элемента
Чтобы избежать взаимодействия с частями шаблона, которые могут быть обработаны в других режимах (например, в текстовом режиме, встраиваемом внутри HTML-шаблона), Thymeleaf 3.0 позволяет избегать атрибуты элементов в его текстовом синтаксисе. Так:
Так что это было бы отлично в шаблоне TEXT (обратите внимание на >):
Конечно, в реальном текстовом шаблоне пример не имеет большого смысла, но это хорошая идея, если мы обрабатываем HTML-шаблон с блоком th:inline=«text», содержащим код выше, и мы хотим убедиться, что наш браузер не принимает <user.age для имени открытого тега при статическом открытии файла в качестве прототипа.
Одним из преимуществ этого синтаксиса является то, что он столь же расширяем, как и разметка. Разработчики могут по-прежнему определять свои диалекты с помощью настраиваемых элементов и атрибутов, применять к ним префикс (необязательно), а затем использовать их в режимах текстового шаблона:
Режимы шаблона JAVASCRIPT и CSS (недоступно для TEXT) позволяют включать код между специальным синтаксисом комментария /*[+...+]*/, чтобы Thymeleaf автоматически раскомментировал такой код при обработке шаблона:
Будет выполнено как:
Вы можете включать выражения внутри этих комментариев, и они будут оцениваться:
Подобным образом, как и для блоков комментариев для прототипа, все три режима текстовых шаблонов (TEXT, JAVASCRIPT и CSS) позволяют инструктировать Thymeleaf для удаления кода между специальными /*[- */ и /* -]*/ маркерами:
Или в TEXT режиме:
Как видно из предыдущей главы, JavaScript и CSS-inlining предлагают возможность включать встроенные выражения в комментарии JavaScript / CSS, например:
… который является действительным JavaScript, и исполняемый код может выглядеть так:
Этот же трюк включения встроенных выражений внутри комментариев может фактически использоваться для всего синтаксиса текстового режима:
Это предупреждение в приведенном выше коде будет показано, когда шаблон открыт статически, потому что он на 100% JavaScript, а также когда шаблон запускается, если пользователь является администратором. Это эквивалентно:
… который на самом деле является кодом, который преобразует исходная версия во время разбора шаблонов.
Обратите внимание, однако, что обертывание элементов в комментариях не очищает строки, в которых они живут (справа до тех пор, пока ; не будет найдено), как это делают inlined выражения. Это поведение зарезервировано только для inlined выражений.
Таким образом, Thymeleaf 3.0 позволяет создавать сложные JavaScript-скрипты и таблицы стилей CSS в виде естественных шаблонов, действительных как прототипом, так и рабочим шаблоном.
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 в виде естественных шаблонов, действительных как прототипом, так и рабочим шаблоном.