如何在Thymeleaf 3

时间:2016-10-13 22:00:39

标签: java thymeleaf

我想使用Thymeleaf 3 layouts向片段添加其他内容,但无法弄清楚如何操作。例如,我想要一个名为layout的片段,如下所示:

<head th:fragment="head(title)">
  <title th:include="${title}">My App: </title>
</head>

然后有一个使用上面片段的模板:

<head th:include="layout :: head(title=~{::title})">
    <title>Please Login</title>
</head>

内容呈现如下:

<head>
    <title>Please Login</title>
</head>

但是,我想修改模板,使其呈现如下所示,并将My App:放在layout模板中(我不想复制它)。< / p>

<head>
    <title>My App: Please Login</title>
</head>

我可以使用以下方法解决此问题:

<head th:fragment="head(title)">
  <title th:include="${title}">My App: <th:block th:include="${title}"></th:block></title>
</head>

然而,Thymeleaf不鼓励使用th:includeFrom the reference

  

th:insert和th:replace之间的区别是什么?   th:包括,自3.0以来不推荐?

有人可以告诉我如何修复我的模板,使其如上所示使用最佳实践呈现(如前所述,参考意味着这意味着不使用th:include)?

1 个答案:

答案 0 :(得分:4)

这里的复杂性来自于您不希望自己的<title>标记直接进入您的片段(通过~{::title}th:replace可以轻松实现片段的<title>标签)。相反,在这里,当您解释时,实际上丰富您的片段的<title>,文本内容来自包含模板。

这里的关键是在标记选择器中使用/text()修饰符,这意味着“选择此标记的文本内容”,如:

<head th:include="layout :: head(title=~{::title/text()})">
    <title>Please Login</title>
</head>

(有关标记选择器语法的完整参考,请参阅http://www.attoparser.org/apidocs/attoparser/2.0.0.RELEASE/org/attoparser/select/package-summary.html

这会使您的title变量包含由单个节点/事件组成的Fragment对象,IText包含文本"Please Login"

正如您所提到的,现在不建议使用th:include(在3.1中弃用),而是th:insertth:replace是首选选项。原因是th:include的机制似乎不是完全立即的,而且常常引起误解(基本上,很多人都认为它做了现在th:insert做的事情,这更简单了)。此外,th:include增加了一些不必要的计算复杂性。

th:replace与2.1完全相同,这就是实际用片段替换主机标签。 th:insert会将片段插入主机标记的正文中。一组更简单的选项,恕我直言。

回到您的代码,我会将其演变为使用th:replace

<head th:replace="layout :: head(title=~{::title/text()})">
    <title>Please Login</title>
</head>

至于你的片段,在你的情况下,我会去内联,这可能是最简单的选择:

<head th:fragment="head(title)">
  <title>My App: [[${title}]]</title>
</head>

请注意,在这种情况下,我们使用Fragment(即片段表达式的结果,在本例中为~{::title/text()}),我们只是通过内联(相当于th:text),好像而不是片段 title变量只包含String。但这是v3.0中新片段表达式灵活性的一部分。

如果您不喜欢内联,可以选择以下内容:

<head th:fragment="head(title)">
  <title th:text="|My App: ${title}|">My App</title>
</head>

如果包含模板可能没有<title>标记,并且您想检查这种可能性,只需使用My App文本作为标题没有标题发送到片段,您可以使用新的 no-op 标记(_):

<head th:fragment="head(title)">
  <title th:text="${title} ? |My App: ${title}| : _">My App</title>
</head>

免责声明,根据StackOverflow规则:我是Thymeleaf的项目负责人。