十二、内联
12.1 表达式内联
尽管标准方言允许我们使用标记属性来执行几乎所有操作,但是在某些情况下,我们更喜欢直接将表达式写到 HTML 文本中。例如,我们可能更喜欢这样编写:
<p>Hello, [[${session.user.name}]]!</p>
…代替此:
<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>
[[...]]
或[(...)]
之间的表达式在 Thymeleaf 中被视为“内联表达式”,并且在它们内部,我们可以使用在th:text
或th:utext
属性中也有效的任何类型的表达式。
请注意,虽然[[...]]
对应于th:text
(即结果将* HTML 转义*),但[(...)]
则对应于th:utext
并且不会执行任何 HTML 转义。因此,使用msg = 'This is <b>great!</b>'
这样的变量,给出以下片段:
<p>The message is "[(${msg})]"</p>
结果将使那些<b>
标签未转义,因此:
<p>The message is "This is <b>great!</b>"</p>
而如果像这样逃脱了:
<p>The message is "[[${msg}]]"</p>
结果将转义为 HTML:
<p>The message is "This is <b>great!</b>"</p>
请注意,我们标记中每个标签的正文(默认不是标签本身)中的“文本内联默认为活动状态”,因此我们无需执行任何操作即可启用它。
内联与自然模板
如果您来自以这种方式输出文本为标准的其他模板引擎,您可能会问:为什么我们从一开始就不这样做?代码少于所有这些代码 th:text
属性!
好吧,要小心,因为尽管您可能会发现内联非常有趣,但是您应该始终记住,当静态打开内联表达式时,它们会逐字显示在 HTML 文件中,因此您可能无法将它们用作设计原型不再!
浏览器不使用内联静态显示代码片段的方式之间的区别…
Hello, Sebastian!
…并使用它…
Hello, [[${session.user.name}]]!
……在设计实用性方面非常明确。
Disabling inlining
不过,可以禁用此机制,因为实际上在某些情况下,我们确实希望输出[[...]]
或[(...)]
序列而不将其内容作为表达式处理。为此,我们将使用th:inline="none"
:
<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>
这将导致:
<p>A double array looks like this: [[1, 2, 3], [4, 5]]!</p>
12.2 文本内联
文本内联与我们刚刚看到的表达式内联功能非常相似,但实际上增加了更多功能。必须使用th:inline="text"
明确启用它。
文本内联不仅使我们能够使用与刚才看到的相同的内联表达式,而且实际上可以像在TEXT
模板模式下处理模板一样处理标签主体,这使我们能够执行基于文本的模板逻辑(而不是仅输出表达式)。
我们将在下一章有关“文本模板模式”的文章中看到更多有关此内容的信息。
12.3 JavaScript 内联
JavaScript 内联允许在HTML
模板模式下处理的模板中更好地集成 JavaScript <script>
块。
与* text inlining 一样,实际上等同于将脚本内容当作JAVASCRIPT
模板模式下的模板一样进行处理,因此 text 模板模式*(请参阅下一章)的所有功能将近在咫尺。但是,在本节中,我们将重点介绍如何使用它将 Thymeleaf 表达式的输出添加到 JavaScript 块中。
必须使用th:inline="javascript"
明确启用此模式:
<script th:inline="javascript">
...
var username = [[${session.user.name}]];
...
</script>
这将导致:
<script th:inline="javascript">
...
var username = "Sebastian \"Fruity\" Applejuice";
...
</script>
上面的代码中有两点需要注意:
首先,JavaScript 内联不仅会输出所需的文本,而且还会用引号将其括起来,并用 JavaScript 对其内容进行转义,以便将表达式结果输出为“格式正确的 JavaScriptLiterals”。
第二,之所以会这样,是因为我们将${session.user.name}
表达式输出为 转义 ,即使用双括号表达式[[${session.user.name}]]
。相反,如果我们使用* unscaped *,例如:
<script th:inline="javascript">
...
var username = [(${session.user.name})];
...
</script>
结果如下所示:
<script th:inline="javascript">
...
var username = Sebastian "Fruity" Applejuice;
...
</script>
…这是格式错误的 JavaScript 代码。但是,如果我们通过附加内联表达式来构建脚本的某些部分,则可能需要输出未转义的内容,因此手头有此工具是件好事。
JavaScript 自然模板
提到的 JavaScript 内联机制的“智能”远远超出了仅应用特定于 JavaScript 的转义并将表达式结果输出为有效 Literals 的范围。
例如,我们可以将(转义的)内联表达式包装在 JavaScriptComments 中,例如:
<script th:inline="javascript">
...
var username = /*[[${session.user.name}]]*/ "Gertrud Kiwifruit";
...
</script>
并且 Thymeleaf 将忽略我们在 Comments 之后和分号之前(在本例中为'Gertrud Kiwifruit'
)写的所有内容,因此执行此操作的结果将与未使用包装 Comments 时的样子完全相同:
<script th:inline="javascript">
...
var username = "Sebastian \"Fruity\" Applejuice";
...
</script>
但是,请仔细查看原始模板代码:
<script th:inline="javascript">
...
var username = /*[[${session.user.name}]]*/ "Gertrud Kiwifruit";
...
</script>
请注意,这是“有效的 JavaScript”代码。当您以静态方式打开模板文件(无需在服务器上执行)时,它将完美执行。
因此,我们这里提供的是一种制作 JavaScript 自然模板的方法!
高级内联评估和 JavaScript 序列化
关于 JavaScript 内联的重要注意事项是,此表达式求值是智能的,并且不仅限于字符串。 Thymeleaf 将使用 JavaScript 语法正确编写以下类型的对象:
- Strings
- Numbers
- Booleans
- Arrays
- Collections
- Maps
- Bean(具有* getter 和 setter *方法的对象)
例如,如果我们有以下代码:
<script th:inline="javascript">
...
var user = /*[[${session.user}]]*/ null;
...
</script>
该${session.user}
表达式将求值为User
对象,Thymeleaf 会将其正确转换为 Javascript 语法:
<script th:inline="javascript">
...
var user = {"age":null,"firstName":"John","lastName":"Apricot",
"name":"John Apricot","nationality":"Antarctica"};
...
</script>
此 JavaScript 序列化的方式是通过org.thymeleaf.standard.serializer.IStandardJavaScriptSerializer
接口的实现来实现的,该接口可以在模板引擎使用的StandardDialect
实例中进行配置。
此 JS 序列化机制的默认实现将在 Classpath 中查找Jackson library,如果存在,将使用它。如果没有,它将应用内置的序列化机制,该机制可以满足大多数方案的需求并产生相似的结果(但灵 Active 较差)。
12.4 CSS 内联
Thymeleaf 还允许在 CSS <style>
标签中使用内联,例如:
<style th:inline="css">
...
</style>
例如,假设我们将两个变量设置为两个不同的String
值:
classname = 'main elems'
align = 'center'
我们可以像这样使用它们:
<style th:inline="css">
.[[${classname}]] {
text-align: [[${align}]];
}
</style>
结果将是:
<style th:inline="css">
.main\ elems {
text-align: center;
}
</style>
请注意,CSS 内联如何也像 JavaScript 一样具有一定的“智能”。具体来说,通过诸如[[${classname}]]
的转义表达式输出的表达式将作为 CSS 标识符 转义。这就是为什么我们的classname = 'main elems'
在上面的代码片段中变成main\ elems
的原因。
高级功能:CSS 自然模板等。
以与之前针对 JavaScript 解释的等效方式,CSS 内联还允许<style>
标签以静态和动态方式工作,即通过将内联表达式包装在 Comments 中来作为 CSS 自然模板 。看到:
<style th:inline="css">
.main\ elems {
text-align: /*[[${align}]]*/ left;
}
</style>
最新评论
Spring Cloud Alibaba 微服务架构实战 https://pan.baidu.com/s/1jF5voFRoeF0lYAzAPBWSbw?pwd=chqk
命令: nload
真是个良心站点哇,大公无私,爱了爱了
还可以直接搞一张映射表,存 uid | time | source_index, 第一次直接查对应的 time 选出前100, 第二次直接用 CompleteFuture 去分别用 source_in
干得漂亮,多个朋友堵条路
2021.2.2版本的不适用吧
现在还可以用么
激活码有用,感谢分享