29 March 2018

Учебник Thymeleaf: Глава 13. Текстовые режимы шаблона

Java
Оглавление

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 (обратите внимание на &gt;):

  [# 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 в виде естественных шаблонов, действительных как прототипом, так и рабочим шаблоном.
Tags:javathymeleaf
Hubs: Java
Comments 8
Ads