Thymeleaf 模板 - 有没有办法装饰模板而不是包含模板片段?
Posted
技术标签:
【中文标题】Thymeleaf 模板 - 有没有办法装饰模板而不是包含模板片段?【英文标题】:Thymeleaf templates - Is there a way to decorate a template instead of including a template fragment? 【发布时间】:2013-09-24 16:04:34 【问题描述】:我是第一次使用 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>
但我想要的实际上是使用模板的相反方式:而不是在页面中包含模板片段,我想在我的模板中包含页面inside,类似这样:
<!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 decorators tags 等效?
谢谢
【问题讨论】:
你试过github.com/ultraq/thymeleaf-layout-dialect吗? @DennisJaamann 我确实正在测试它。 【参考方案1】:使用 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。
【讨论】:
谢谢,这很适合我们这些用过jsp标签的人 @VadimFerderer:我不明白你的意见。这很好用 - 您可以在好的,正如 Sotirios Delimanolis 所说,Thymeleaf 不支持这种使用模板的方式,或者我应该说“分层布局”,正如 Daniel Fernandez 在this thread 中所解释的那样。
由于 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>
【讨论】:
备考你应该添加解决它的代码并接受你自己的答案:) @DennisJaamann 你是对的,我想添加代码,即使它与 Layout 项目文档中提供的完全相同。要接受我的回答,我得等明天:) 非常有帮助。谢谢。 你好,你知道是否有一种方法可以使用布局方言来保留父级的内容,而不是覆盖它?含义:最终结果将呈现<!-- include here the content of the current page visited by the user --> Hello world
而不仅仅是Hello world
。当然,这无需将<!-- include here the content of the current page visited by the user -->
移动到<div layout:fragment="content">
之外。谢谢【参考方案3】:
你需要
<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/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>
【讨论】:
【参考方案4】:据我所知,你不能。一种可能的解决方案是创建一个ViewResolver
,它始终转发到您的decorator
文件,但同时放置Model
属性,该属性将具有您想要包含的片段的实际路径。
【讨论】:
以上是关于Thymeleaf 模板 - 有没有办法装饰模板而不是包含模板片段?的主要内容,如果未能解决你的问题,请参考以下文章