Шаблоны Thymeleaf-есть ли способ украсить шаблон вместо включения фрагмента шаблона?

Я работаю с 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>

но то, что я хочу, на самом деле противоположный способ использования шаблона : вместо включения фрагмента шаблона на странице Я хочу включить страницу внутри мой шаблон, что-то вроде этого:--5-->

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

другими словами, есть ли способ, чтобы иметь эквивалент Sitemesh декораторы теги в Thymeleaf?

спасибо

4 ответов


С Thymeleaf 2.1 вы можете написать что-то вроде этого:

создайте шаблон (например. шаблоны/макет.HTML) и добавьте th: fragment= "страница" информация в теге html и определить область содержимого с 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>

Теперь создайте страницу, которая будет включать этот шаблон добавления th: include= "шаблоны / макет :: страница" в теге html и поместите свой основной контент внутри div с th: fragment= "content"

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


хорошо, как указано Sotirios Delimanolis, Thymeleaf не поддерживает этот способ использования шаблона, или я должен сказать"иерархическая макетов", как объяснил Даниэль Фернандес в этой теме.

поскольку sitemesh и Thymeleaf совместимы, кажется, что я должен использовать оба решения. Очень плохо.

Edit: как предложил DennisJaamann в комментарии, я, наконец, использовал Thymeleaf Макет Диалект, диалект представления, который обеспечивает функция, которую я искал.

работающий код:

сначала я добавить 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>

вам нужно

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

если Теперь создайте папку с именем template в папке views.

вид/дом.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>

вид/макет/макет.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>

насколько я знаю, вы не можете. Возможным решением было бы создать ViewResolver это всегда вперед к вашему decorator file, но при этом put Model атрибуты, которые будут иметь фактический путь к фрагменту, который вы хотите включить.