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>
但是我想要的实际上是与使用模板相反的方式:而不是在页面中包含模板片段,我想要在我的模板中包含页面,就像这样:
<!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装饰器标签 ?
谢谢
与Thymeleaf 2.1,你可以写这样的事情:
创build模板(例如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>
现在创build一个包含这个模板的页面,在html标签中添加:include =“templates / layout :: page” ,并将你的主要内容放在一个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>
在布局页面中,可以使用this (th:include =“this :: content”)或者禁止这个选项(th:include =“:: content”)。 这似乎是我认为的jsf facelets。
好吧,正如Sotirios Delimanolis所说,Thymeleaf不支持这种使用模板的方法,或者我应该说“ 分层布局 ”,正如Daniel Fernandez在这个主题中所解释的那样。
由于Sitemesh和Thymeleaf是兼容的,似乎我必须使用这两种解决scheme。 太糟糕了。
编辑:正如DennisJaamann在评论中所build议的那样,我最终使用了Thymeleaf Layout Dialect ,这是一种提供我所需要的function的视图方言。
工作代码:
首先我添加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; }
然后,我创build模板(例如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
的模板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>
据我所知,你不能。 一个可能的解决scheme是创build一个ViewResolver
,它总是转发到你的decorator
文件,但同时把Model
属性放在你想要包含的片段的实际path中。
你需要
<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; }
如果现在在视图文件夹中创build一个名为模板的文件夹。
意见/ 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>