Thymleaf 模板模式中有三种被认为是文本模式: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 模板,可以在文本模板模式下执行。
但为了包含比输出表达式更复杂的逻辑,我们需要一种新的非基于标记的语法:
[# th:each="item : ${items}"] - [(${item})] [/]
这实际上是更冗长的精简版:
[#th:block th:each="item : ${items}"] - [#th:block th:utext="${item}" /] [/th:block]
请注意,该新的语法是如何基于声明为 [#Element ...] 而不是 <element ...> 的元素(即处理标签)的。元素像 [#Element ...] 一样打开,并且像[ /element] 一样关闭,可以通过以 A / 几乎等同于 XML 标签的方式来声明独立标签:[#Element ... /]。
标准方言仅包含这些元素之一的处理器:已经知道的 th:block,尽管我们可以在方言中扩展它并以通常的方式创建新元素。另外,th:block 元素([#th:block ...] ... [/th:block])允许缩写为空字符串([# ...] ... [/]),所以上面的 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 页面调用。请注意,这不是 HTML模板中的 <script> 块,而是一个 .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 允许对其文本语法中的元素属性进行转义。所以:
(1)在 TEXT 模板模式下的属性是 HTML-unescaped
(2)在 JAVASCRIPT 模板模式下的属性是 JavaScript-unescaped
(3)在 CSS 模板模式下的属性是 CSS-unescaped
因此,这在 TEXT 模板模式中是完全可以的(请注意 >):
[# th:if="${120<user.age}"] Congratulations! [/]
当然,这个 < 在一个真正的文本模板中是没有意义的,但如果我们在处理一个 HTML 模板时,其中有一个 th:inline="text" 块,包含上面的代码,并且我们想确保我们的浏览器在静态打开文件时,不会把这个 <user.age 当作一个开放标签的名字,这是一个好主意。
这种语法的优点之一是,它和标记语法一样具有可扩展性。开发人员仍然可以用自定义的元素和属性来定义他们自己的方言,给它们应用一个前缀(可选),然后在文本模板模式中使用它们:
[#myorg:dosomething myorg:importantattr="211"]some text[/myorg:dosomething]