web-dev-qa-db-ja.com

Thymeleafテンプレート-テンプレートフラグメントを含める代わりにテンプレートを装飾する方法はありますか?

私は初めてThymeleafで作業していますが、テンプレートについて明確にする必要があります。ドキュメントを正しく理解していれば、ページにincludeincludeテンプレート(またはその一部)を含めることができます。したがって、たとえば、私はそのようなものを書くことができます:

<!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>

しかし、私が欲しいのは、実際にはテンプレートを使用する反対の方法です:ページにテンプレートフラグメントを含める代わりに、ページを含めたいinsidemyテンプレート、そのようなもの:

<!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デコレータタグ に相当する方法はありますか?

ありがとう

38
Romain Linsolas

OK、Sotirios Delimanolisが述べたように、Thymeleafはテンプレートの使用方法をサポートしていません。または、Daniel Fernandezが this thread で説明したように、「Hierarchical layouts」と言います。

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>
20
Romain Linsolas

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 = "で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>

レイアウトページでは、this(th:include = "this :: content")を使用するか、このオプションを抑制できます(th :include = ":: content")。 jsf faceletsのようです。

67
ÉricoGR

あなたが必要

<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;
}

ここで、viewsフォルダーにtemplateという名前のフォルダーを作成します。

views/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>

views/layout/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>
1
mrclrchtr

私の知る限り、できません。可能な解決策は、常にViewResolverファイルに転送するdecoratorを作成すると同時に、フラグメントへの実際のパスを持つModel属性を置くことです。含めたい。