39

我是第一次使用 Thymeleaf,我需要澄清一下模板。如果我正确理解了文档,我可以在我的页面中包含一个模板——或者只是其中的一个片段。例如,我可以这样写:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head th:include="template/layout :: header">
    </head>
    <body>
        Hello world
        <div th:include="template/layout :: footer"></div>
    </body>
</html>

但我想要的实际上是使用模板的相反方式:我不想在页面中包含模板片段,而是想我的模板中包含页面,如下所示:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    ...
</head>
<body>

    <div id="my-template-header">...</div>

    <div id="the-content">
        <!-- include here the content of the current page visited by the user -->
        ???
    </div>

    <div id="my-template-footer">...</div>
</body>

换句话说,有没有办法在 Thymeleaf 中拥有等效的Sitemesh 装饰器标签

谢谢

4

4 回答 4

67

使用 Thymeleaf 2.1,您可以编写如下内容:

创建模板(例如templates/layout.html),并在html标签中添加th:fragment="page"信息,并用th:include="this :: content"信息定义内容区域:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      th:fragment="page">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Test</title>
    </head>
    <body>
        layout page
        <div th:include="this :: content"/>
        layout footer
    </body>
</html>

现在创建将包含此模板的页面,在 html 标记中添加th:include="templates/layout :: page"并将您的主要内容放在th:fragment="content"的 div 中

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      th:include="templates/layout :: page">
    <head>
        <title></title>
    </head>
    <body>
        <div th:fragment="content">
            my page content
        </div>
    </body>
</html>

在布局页面中,您可以使用选项(th:include="this :: content")或取消此选项(th:include=":: content")。我认为这似乎是 jsf facelets。

于 2013-12-08T02:33:31.357 回答
20

好的,正如 Sotirios Delimanolis 所说,Thymeleaf 不支持这种使用模板的方式,或者我应该说“分层布局”,正如 Daniel Fernandez 在这个线程中所解释的那样。

由于 sitemesh 和 Thymeleaf 是兼容的,看来我必须同时使用这两种解决方案。太糟糕了。

编辑:正如 DennisJaamann 在评论中所建议的,我终于使用了 Thymeleaf Layout Dialect,一种提供我正在寻找的功能的视图方言。

工作代码:

首先我添加LayoutDialect类:

@Bean
public ServletContextTemplateResolver templateResolver() {
    ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".html");
    //NB, selecting HTML5 as the template mode.
    resolver.setTemplateMode("HTML5");
    resolver.setCacheable(false);
    return resolver;
}

然后,我创建模板(例如templates/layout.html),并layout:fragment在我想要放置当前页面内容的位置添加信息:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    ...
</head>
<body>
    <div id="my-template-header">...</div>

    <div id="the-content" layout:fragment="content">
        <!-- include here the content of the current page visited by the user -->
    </div>

    <div id="my-template-footer">...</div>
</body>

并且页面将引用具有以下属性的模板layout:decorator

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="templates/layout">
<body>

    <div layout:fragment="content">
        Hello world
    </div>

</body>
</html>
于 2013-09-19T14:55:49.520 回答
1

你需要

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>1.2.2</version>
</dependency>

并将其添加到您的 SpringTemplateEngine:

@Bean
@Description("Thymeleaf template engine with Spring integration")
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver());
    templateEngine.addDialect(new LayoutDialect());

    return templateEngine;
}

如果现在在您的视图文件夹中创建一个名为模板的文件夹。

意见/home.html

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
  layout:decorator="template/layout">
 <body>
  <div layout:fragment="content">
    Hello world
  </div>
 </body>
</html>

视图/布局/layout.html

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:th="http://www.thymeleaf.org"
        xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head>
      </head>
        <body>
          <div id="content" layout:fragment="content">
          </div>
</body>
</html>
于 2014-03-29T02:04:38.053 回答
0

据我所知,你不能。一种可能的解决方案是创建一个ViewResolver始终转发到您的decorator文件的,但同时放置Model具有您想要包含的片段的实际路径的属性。

于 2013-09-19T14:13:24.863 回答