Thymeleaf布局方言和head中的th:replace导致标题为空

8
我是在按照这个教程操作:http://www.thymeleaf.org/doc/layouts.html(到达Thymeleaf Layout Dialect一节)。 其中有一个例子:
<!DOCTYPE html>
<html>
  <head>
  <!--/*  Each token will be replaced by their respective titles in the resulting page. */-->
    <title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Task List</title>
    ...
  </head>
  <body>
    <!--/* Standard layout can be mixed with Layout Dialect */-->
    <div th:replace="fragments/header :: header">
    ...
    </div>
    <div class="container">
      <div layout:fragment="content">
      ...
      </div>
      <div th:replace="fragments/footer :: footer">&copy; 2014 The Static Templates</div>
    </div>
  </body>
</html>

在上面的例子中,页脚和页眉通过th:replace标签进行替换,而布局文件中<head>标签具有<title>标签。
基本上,我想用th:replace替换整个<head>标签。因此,我的布局文件如下:
<!DOCTYPE html>
<html>
<head th:replace="/html/components/head :: head">
</head>
<body>
     <div layout:fragment="content">
     </div>
...
     <div th:replace="/html/components/footer :: footer" />
</body>
<html>

我的内容文件:

<!DOCTYPE html>
<html layout:decorator="/html/layouts/layout">
<head>
    <title>My content title</title>
</head>
<body>
      <div layout:fragment="content">
      ...
      </div>
</body>
</html>

最后是我的 /html/components/head.htm 文件:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head th:fragment="head">
<meta charset="utf-8" />
<title layout:title-pattern="$CONTENT_TITLE">Layout Title should be replaced by Content Title!</title>
...
</head>
<body>
</body>
</html>

内容没问题。页脚和页头已按预期从文件中替换,但页面标题为空!

我得到:

<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title></title>
...

出了什么问题?


如果我简单地删除 <head th:replace="/html/components/head :: head"> 并将 head 文件的内容直接放到 layout.htm 中,则标题可用。但是我不喜欢这种解决方案的丑陋程度。有没有办法移动整个 head 部分并将其与布局分离? - iaforek
3个回答

32

最终,我找到了实现我想要的方式。

在布局文件中,<title>标签必须保留。我将所有其他标签与<object>标签分组,并进行如下注释:

<head>
  <title layout:title-pattern="$CONTENT_TITLE">Layout Title will be replaced by Page Title!</title>
  <object th:include="/html/components/head :: head" th:remove="tag" />
</head>

在我的html/components/head.htm文件中,我不得不删除<title>标签,以免在包含后出现重复。

<head th:fragment="head">
  <meta charset="utf-8" />
  <!-- NO TITLE TAG HERE -->
  ...
</head>

这种方式头部片段被包含在 <object> 标签中,而且由于使用了 th:remove="tag"<object> 标签被删除,最终的 HTML 输出如下:

<head>
  <title>My content title</title>
  <meta charset="utf-8" />
  <!--  NO TITLE TAG HERE -->
  ...
</head>

显然,我已经删除了“NO TITLE TAG HERE”这个消息,一旦我使它正常工作。


2
我建议您使用<meta th:include="/html/components/head :: head" th:remove="tag" />,因为一些IDE(例如IntelliJ)会将标签object标记为不允许在head中使用。 - Lorenzo Polidori
1
你也可以使用<div th:replace="/html/components/head :: head" />,这将产生相同的效果。 - Jelle Blaauw
哦!非常感谢你)) - Orkhan Hasanli

7
我认为我找到了一种更简洁的方法来使用th:replaceth:fragment,例如在页面中包含常见的<head>元数据和静态资源包含。
片段定义中放置th:remove="tag",这样您就不必每次都重复th:remove="tag"fragment_head.html
<thymeleaf xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" 
    th:fragment="head" th:remove="tag">

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" th:href="@{/css/vendor/bootstrap.min.css}"/>

</thymeleaf>

mypage.html

<head>
    <thymeleaf th:replace="fragment_head :: head" />
</head>

1
你可以替换整个 head 标签。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="pl" th:replace="fragments/head :: head">
</head>
<body>
 ...
</body>
</html>

resources/templates/fragments/head.html:

    <head lang="pl">
        <title>Title</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <link href="http://cdn.jsdelivr.net/webjars/bootstrap/3.3.5/css/bootstrap.min.css"
              th:href="@{/webjars/bootstrap/3.3.5/css/bootstrap.min.css}"
              rel="stylesheet" media="screen" />

        <script src="http://cdn.jsdelivr.net/webjars/jquery/2.1.4/jquery.min.js"
                th:src="@{/webjars/jquery/2.1.4/jquery.min.js}"></script>
        <link href="../static/css/mycss.css"
              th:href="@{css/mycss.css}" rel="stylesheet" media="screen"/>
    </head>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接