Шаблоны 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>
Другими словами, существует ли способ получить эквивалент тегов декораторов Sitemesh в Thymeleaf?
Спасибо
Ответы
Ответ 1
Хорошо, как заявил Sotirios Delimanolis, Thymeleaf не поддерживает этот способ использования шаблона, или я должен сказать "Иерархические макеты", как объяснил Даниэль Фернандес в этой теме.
Поскольку sitemesh и 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>
Ответ 2
с Thymeleaf 2.1, вы можете написать что-то вроде этого:
Создайте шаблон (например, templates/layout.html) и добавьте в тег html информацию th: фрагмент = "страница" и определите область содержимого с помощью 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" и поместите основной контент внутри div с th: фрагментом = "содержание"
<!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.
Ответ 3
Насколько я знаю, вы не можете. Возможным решением было бы создать ViewResolver
, который всегда пересылается в ваш файл decorator
, но в то же время помещает атрибуты Model
, которые будут иметь фактический путь к фрагменту, который вы хотите включить.
Ответ 4
Вам нужно
<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 в вашей папке представлений.
просмотров/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>