Szablony tymeleaf - czy istnieje sposób na udekorowanie szablonu zamiast umieszczania fragmentu szablonu?

Pracuję z Tymeleafem po raz pierwszy i potrzebuję wyjaśnienia co do szablonów. Jeśli dobrze rozumiem dokumentację, mogę Umieścić szablon-lub tylko jego fragment - na mojej stronie. Więc na przykład mogę napisać coś takiego:

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

Ale to, czego chcę, to w rzeczywistości odwrotny sposób użycia szablonu : zamiast umieszczać fragment szablonu na stronie, chcę umieścić Stronę wewnątrz mojego szablonu, coś w rodzaju że:

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

Innymi słowy, czy istnieje sposób na posiadanie odpowiednika znaczników Sitemesh W Thymeleaf?

Dzięki

Author: Mahozad, 2013-09-19

4 answers

Z Thymeleaf 2.1 możesz napisać coś takiego:

Utwórz szablon (dla ex. szablony/layout.html) i dodać th:fragment="page" informacje w tagu html i zdefiniować obszar zawartości za pomocą th:include="this :: content" information:

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

Teraz Utwórz stronę, która będzie zawierać ten szablon dodając th:include="templates/layout:: page" w znaczniku html i umieść główną zawartość w div z 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>

Na stronie layout możesz użyć to (th: include="this:: content") lub wyłącz tę opcję (TH: include=":: content"). Wydaje mi się, że JSF facelets.

 65
Author: ÉricoGR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 10:44:57

Ok, jak stwierdził Sotirios Delimanolis, Thymeleaf nie wspiera takiego sposobu użycia szablonu, czy powinienem powiedzieć "hierarchiczne układy ", jak wyjaśnił Daniel Fernandez w Ten wątek.

Ponieważ sitemesh i Thymeleaf są kompatybilne, wydaje się, że muszę użyć obu rozwiązań. Szkoda.

Edit: zgodnie z sugestią Dennisjaamanna w komentarzu, w końcu użyłem dialektu układu Thymeleaf , dialektu widoku, który zapewnia funkcję, której szukałem za.

Kod roboczy:

Najpierw dodaję LayoutDialect klasę:

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

Następnie tworzę szablon (dla np. templates/layout.html), i dodać informację layout:fragment gdzie chcę umieścić zawartość bieżącej strony:

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

I strona będzie odwoływać się do szablonu z atrybutem 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
Author: romaintaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-20 12:20:16

Potrzebujesz

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

I dodaj to do 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;
}

Jeśli teraz utwórz folder o nazwie szablon w folderze widoki.

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
Author: mrclrchtr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-29 02:04:38

Z tego, co wiem, nie możesz. możliwym rozwiązaniem byłoby utworzenie ViewResolver, która zawsze będzie przekazywana do Twojego pliku decorator, ale jednocześnie umieść Model atrybuty, które będą miały aktualną ścieżkę do fragmentu, który chcesz dołączyć.

 0
Author: Sotirios Delimanolis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-19 14:13:24