Thymeleaf 页面布局 header 属性被覆盖

Thymeleaf page layout header properties overriden

好的,我正在使用 thymeleaf page layouts

它似乎工作正常,但是,我想知道如何在使用片段的页面的 <head></head> 中配置 <title></title> 属性?目前,head 中的所有内容都被 header 片段覆盖(如下所示)。

这是我的:resources/templates/fragments/header.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
    <link href="../../static/css/bootstrap.min.css" th:href="@{css/bootstrap.min.css}" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" th:src="@{js/bootstrap.min.js}"></script>
</head>
<body></body>
</html>

这是我的索引页(我要显示标题标签):

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">

<head th:include="fragments/header :: header">
    <title>THIS DOES NOT SHOW</title>
</head>
<body>
    <div class="container">
        <div th:include="fragments/headerNavbar :: headerNavbar"></div>

        <h1>hey</h1>
        <div class="btn btn-success">button</div>
        <button class="btn btn-success">another</button>       
    </div>

这是实际的 HTML 输出:

 <head>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script src="js/bootstrap.min.js"></script>
</head>

我明白是怎么回事了。 header 片段正在加载(包含)到我的索引页面的头部,因此它覆盖了所有属性。

我的问题是我不知道如何拥有 header 片段并让文件在指定 属性 时使用该片段,例如标题。

这是我在索引文件中尝试过的:

<head>
    <div th:include="fragments/header :: header"></div>
    <title>THIS DOES NOT SHOW</title>
</head>

但这真的把我的HTML搞得一团糟。必须有一个简单的解决方案吗?

好的,我找到了使用这个 solution 的方法。我仍然认为它很笨重,而且我仍然认为必须有更好的方法,但对于我的需要来说,这已经足够了(如果你有解决方案,请分享一个解决方案):

魔法在于 th:remove="tag",在运行时,对象标签被删除并适当地显示片段:

<head>
    <title>THIS DOES SHOW</title>
    <object th:include="fragments/header :: header" th:remove="tag"><object> 
</head>

所以现在输出是:

<head>
    <title>THIS DOES SHOW</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script src="js/bootstrap.min.js"></script>
</head>

您可以使用 Thymeleaf Layout Dialect,它通过新属性提供对分层布局的支持。这些属性类似于 Thymeleaf 的属性,但提供了额外的功能。

例如,它允许将布局头部的内容与提供 body 部分的页面的头部内容混合。

您必须创建一个模板以用作页面的布局。根据你的例子,你会得到这样的东西:

文件resources/templates/layouts/layout.html

<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
  <head>
    <link href="../../static/css/bootstrap.min.css" th:href="@{css/bootstrap.min.css}" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" th:src="@{js/bootstrap.min.js}"></script>
    <title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">My app</title>
  </head>
  <body>
    <section layout:fragment="content">
        <!-- Content replaced by each page's content fragment -->
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          Praesent scelerisque neque neque, ac elementum quam dignissim interdum.
        </p>
    </section>
  </body>
</html>

文件resources/templates/index.html

<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 
      layout:decorator="layouts/layout">
<head>
    <title>Home page</title>
</head>
<body>
    <div layout:fragment="content">
        <h1>hey</h1>
        <div class="btn btn-success">button</div>
        <button class="btn btn-success">another</button>       
    </div>
</body>
</html>

这样生成的页面将具有以下头部部分:

<head>
  <link href="../../static/css/bootstrap.min.css" th:href="@{css/bootstrap.min.css}" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" th:src="@{js/bootstrap.min.js}"></script>
  <title>My app - Home page</title>
</head>

请注意 layout:title-pattern 属性,该属性允许设置模式以生成最终标题。默认情况下,布局方言将合并页面头部中也包含的任何脚本或样式表。为了简单起见,我没有包含 header、页脚、菜单等的任何片段,但它也受支持。

查看项目页面,了解您必须向项目添加哪些依赖项以及所需的配置。如果您使用的是 boot,Thymeleaf 启动器已经支持这种方言,因此您只需将依赖项添加到您的项目中,它就会自动配置。

编辑: 我更正了布局示例中的错字,使用的是 layout:include 而不是 layout :片段.