欢迎您的访问
专注于分享最有价值的互联网技术干货

十二、内联

几个T的资料等你来白嫖
双倍快乐

十二、内联

12.1 表达式内联

尽管标准方言允许我们使用标记属性来执行几乎所有操作,但是在某些情况下,我们更喜欢直接将表达式写到 HTML 文本中。例如,我们可能更喜欢这样编写:

<p>Hello, [[${session.user.name}]]!</p>

…代替此:

<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>

[[...]][(...)]之间的表达式在 Thymeleaf 中被视为“内联表达式”,并且在它们内部,我们可以使用在th:textth: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>
赞(0) 打赏
版权归原创作者所有,任何形式转载请联系我们:大白菜博客 » 十二、内联

评论 抢沙发

2 + 6 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏