Thymeleaf是现代化服务器端的Java页面模板引擎,不同于JSP和FreeMarker,Thymeleaf的语法更加接近HTML
Thymeleaf是面向Web和独立环境的现代服务器端Java模板引擎。
Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板 - 可以正确显示在浏览器中的HTML,也可以作为静态原型工作,从而在开发团队中进行更强大的协作。
随着Spring框架的模块,与您最喜欢的工具的集成,以及插入自己的功能的能力,Thymeleaf是现代HTML5 JVM Web开发的理想选择,尽管它可以做的更多。
好吧,我承认刚才那段是Thymeleaf官方的说明,我只不过机翻了一下。下面咱们说点人话。Thymeleaf就是jsp的高端升级版。
springboot官方的支持与推荐
Spring Boot为以下的模板引擎提供自动配置支持: 1.FreeMarker 2.Groovy 3.Thymeleaf 4.Velocity(1.4已不再支持) 5.Mustache
注:由于在内嵌servlet容器中使用JSPs存在一些已知的限制,所以建议尽量不使用它们。 使用以上引擎中的任何一种,并采用默认配置,则模块会从 src/main/resources/templates 自动加载。
|
引用:Spring Boot参考指南
ThymeLeaf是一个健康的开源项目:每个月都有新的特性、良好的文档、响应性的用户论坛 如果您希望web设计器能够读取视图文件,那么它是理想的模板引擎。所使用的表达式语言(实际上称为标准方言)比JSP表达式语言强大得多。与JSP不同,Thymeleaf适用于富HTML电子邮件(参见http://www.thymeleaf.org/springmail.html). |
引用:SpringMVC:从JSP和Tiles到Thymeleaf
Thymeleaf显然是一个开发页面的技术,现在各种前端技术层出不穷,比如现在主流的Vue、React、AngularJS等。很多人可能会要问,这个Thymeleaf相对于这些前端框架到底有啥优势。
其实,Thymeleaf跟那些前端框架根本不是一个类型的东西,也没有啥可比性。
Thymeleaf和老牌的jsp属于非前后分离的思路来开发的。后端通过数据渲染html的模板,渲染后模板就是个完整的html页面,将页面返回给请求方。
主流的前端框架是基于前后端分离的思路来开发的,前端页面通过ajax来调用后端的rest接口来获取数据,再通过js进行渲染页面(不管什么前端技术其实都是对js进行了封装,js依然是底层核心)。
使用前后分离主要有下面几个好处
说了这么多前后分离的好处,你可能就要问了,那我们为什么还要用那个看起来那么low的模板引擎呢?
为了速度。前后分离方式,前端页面通过ajax来调用后端的rest接口来获取数据,再通过js进行渲染页面。获取数据和通过js渲染页面的代码,很多时候比页面本身要多的多,而且通过js来操作dom进行渲染,稍微复杂些的页面往往就会把渲染逻辑搞的错综复杂。相信从jsp时代一路走到现在的老程序员都深知工作量是成倍的往上翻。
固然刚才列举了前后分离的种种好处,但这些好处大多数都是集中在app开发上,其他某些场景下这些好处并不明显。最典型的一个场景就是管理后台。管理后台往往对页面的花哨性要求不高,并发量也不大,而且功能往往还不少。这种场景下,前后分离技术上导致的工作量大幅度增加,人员上分离导致额外的联调成本都成了不少的负担。Thymeleaf作为模板引擎这时候优势就非常大。只需要在html原型的页面上稍微加几个标签,即可完成渲染。而且加上的标签并不影响原型页面直接通过html打开。
说了这么多,总结一下,Thymeleaf是一个供后端人员使用的,为快速开发页面而生的Java模板引擎。
http://www.thymeleaf.org"> |
本文侧重点是总结和讲解thymeleaf的常用标签,表达式及表达式对象的使用
th:text 用于文本的显示,并且可以进行简单的计算。
th:utext 用于html的文本替换,常用于富文本编辑器编辑后的内容显示到前台页面上。
->my name is maliming
th:if 用于判断条件,还可以多条件 and,or(二元操作符),!,not非(一元操作符)。
show 如果user对象为空则不显示,不为空则显示 -> show
show
不能用"<",">"等符号,要用"lt"等替代 |
运算符还可以写在${}里
运算符扩展
进制运算符:+,-,\*,/,% 负号:- 二进制运算符:and 、or 布尔否定:!,not 比较运算符:>,<,> =,<=(gt,lt,ge,le) 相等运算符:==,!=(eq,ne) 字符串连接:+ 文本替换:|The name is ${name}| 条件运算符: If-then:\(if\) ? \(then\) If-then-else:\(if\) ? \(then\) : \(else\) Default:\(value\) ?: \(defaultvalue\)
|
th:unless 用于判断条件,与th:if作用相反。
th:switch th:case 用于多个同等级相同目的判断,多选一时使用。
first
若${user.name}中的值为maliming则显示,否则不显示
second
th:action 用于定义后台控制器的路径,表单的提交地址,相当于
th:each 用于遍历集合中的对象,相当于jstl中的
List集合循环遍历
其中的user是临时变量,相当于for(User user : users)中的user,userStat称为状态变量,属性有index:当前迭代对象的index(从0开始计算),count: 当前迭代对象的index(从1开始计算), size:被迭代对象的大小,current:当前迭代变量,even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算), first:布尔值,当前循环是否是第一个,last:布尔值,当前循环是否是最后一个。
Map集合循环遍历
数组循环遍历
th:value 用于属性赋值。
->
th:src 用于外部资源的引入,例如图片,js文件。
或
th:remove 用于删除。可以表达式传参。
|
这里的
标签中有th:remove="all-but-first",意思是只保留标签中的第一个字标签,也就是name为Tom的所在all:删除所在标签和内容及其所属的所有子标签。body:删除所在标签的内容及其所属的所有子标签。tag:删除所在标签,不删除任何所属的子标签。all-but-first:删除除第一个子标签外的其他子标签。none:不起作用,什么也不做。
th:selected 用于选择框设置选中值。通常和th:each一起使用。
|
1.13 th:object 用于表单数据对象绑定,后台controller中参数保持一致,和选择(星号)表达式。
public ModelAndView addUser(@RequestParam(value = "user") User user,ModelMap model){}
|
th:attr 用于设置任意属性
设置单个属性。
设置多个属性之间用逗号隔开。
在我们的模板中,我们经常希望从其他模板中包含某些部分,如页脚,页眉,菜单等部分
为了做到这一点,Thymeleaf需要我们定义这些部分“片段”,以供其他模版包含,可以使用th:fragment属性来定义被包含的模版片段。
copy"> © 2011 The Good Thymes Virtual Grocery |
上面的代码定义了一个名为copy的片段,我们可以使用th:insert或th:replace属性(以及th:include,尽管Thymeleaf 3.0不再推荐使用它),容易地包含在我们的主页中:
...
|
请注意,th:insert期望一个片段表达式(〜{...})。 在上面的例子中,这是一个简单的片段表达式,(〜{,})包围是完全可选的,所以上面的代码将等价于:
... |
fragment加载语法如下:
templatename::selector:”::”前面是模板文件名,后面是选择器
::selector:只写选择器,这里指fragment名称,则加载本页面对应的fragment
templatename:只写模板文件名,则加载整个页面
模板名和选择器都可以是表达式(甚至是条件表达式!)
也可以使用th:replace
th:insert和th:replace(th:include)之间的区别
th:insert和th:replace之间有什么区别?(th:include在3.0之后不推荐使用了)?
th:insert是最简单的:它将简单地插入指定宿主标签的标签体中。
th:replace实际上用指定的片段替换其宿主标签。替换当前标签为模板中的标签,加载的节点会整个替换掉加载他的div
th:include类似于th:insert,⽽而不是插入片段,它只插入此片段的内容。
可参数化的片段签名
为了使模板片段具有多类似函数的功能,用th:fragment定义的片段可以指定一组参数:
... |
可以通过以下两种语法中的一种来引用上述模版⽚段,下面的th:replace改成th:insert也是一样的:
... ... |
不带片段参数的片段局部变量
即使片段没有定义参数:
...
|
我们可以使用上面指定的第二个语法来调用它们(只有第二个语法才可以):
|
上面的代码等价于th:replace和th:with的组合:
|
请注意,片段的局部变量规范 - 无论是否具有参数签名 - 都不会导致上下
文在执行之前被清空。片段仍然能够访问调用模板中正在使用的每个上下文变量。
由于片段表达式的强大功能,我们不仅可以为片段指定文本类型,数字类型,bean对象类型的参数,还可以指定标记片段作为参数。
这允许我们以一种方式创建我们的片段,使得它们可以调用户模板的标记,从而产生非常灵活的模板布局机制。
请注意在下面的片段中使用标题和链接变量:
|
我们现在调用这个片段:
|
结果将使用调用模板中的实际
|
Thymeleaf标准方言中唯一的元素处理器(不是属性)是:th:block。
th:block是一个只允许模板开发人员指定他们想要的属性的属性容器。
Thymeleaf将执行这些属性,然后简单地制作块。
所以它可能是有用的,例如,当为每个元素创建多个
|
Thymeleaf模板中的三个模板被认为是问本:TEXT,JAVASCRIPT和CSS。 这将它们与标记模板模式区分开来:HTML和XML。
文本模板模式和标记模式之间的关键区别在于,在文本模板中,没有标签以属性的形式插⼊逻辑,因此我们必须依赖其他机制。最基本的机制是内联, 内联语法是以文本模板模式输出表达式结果的最简单方法,因此邮件形式模板来说,内联是最好的机制。
内联文本
Hello, [[#{test}]] |
内联JavaScript
... var username = [[${session.user.name}]]; ... |
内联CSS
Thymeleaf还允许在CSS
例如,假设我们有两个变量设置为两个不同的String值:
classname = 'main elems'
align = 'center'
我们可以这样做:
.[[${classname}]] { text-align: [[${align}]]; } |
输出结果如下:
.main\ elems { text-align: center; } |
变量表达式:$ {...}
选择变量表达式:* {...}
消息表达式:#{...}
链接网址表达式:@ {...}
片段表达式:〜{...} |
变量表达式 ${}
上述代码为引用user对象的name属性值
选择表达式*{}
我们不仅可以将变量表达式写为$ {...},还可以作为* {...}。
这两种方式有一个重要的区别:星号语法计算所选对象而不是整个上下⽂
的表达式。 也就是说,只要没有选定的对象,$和*语法就会完全相同。
什么是选定对象? 使用th:object属性的表达式的结果。 我们在用户个⼈
资料(userprofile.html)页面中使用一个:
Name: Sebastian .
Surname: Pepper.
Nationality: Saturn< /span>.
|
这完全等同于:
Name: Sebas tian.
Surname: Pep per.
Nationality: y}">Saturn.
|
选择表达式一般跟在th:object后,直接取object中的属性
URL表达式 @{}
@{... ...}支持决定路径和相对路径。其中相对路径又支持跨上下文调用url和协议的引用
当URL为后台传出的参数时,代码如下:
片段表达式〜{}
代码片段表达式是表示标记片段的简单方法,并将其移动到模板周围。
这允许我们复制它们,将它们传递给其他模板作为参数,等等。
最常用的用法是使⽤th:insert或th:replace进行片段插入:
... |
它们可以在任何地方使用,就像任何其他变量一样:
|
文字国际化表达式 #{}
Welcome to our grocery store!
调用国际化的welcome语句,国际化资源文件如下
resource_en_US.properties:home.welcome=Welcome to here!
resource_zh_CN.properties:home.welcome=欢迎您的到来!
我们已经提到$ {...}表达式实际上是在上下文中包含的变量的映射上执行的OGNL(Object-Graph Navigation Language)对象
${} 中预存对象(表达式中基本对象)
当对上下文变量计算OGNL表达式时,某些对象可用于表达式以获得更高的灵活性。 这些对象将被引用(按照OGNL标准),从#符号开始(请注意,这些对象不是Map集合/命名空间):
#ctx:上下文对象。
#locale:上下文区域设置。
#vars:上下文变量。
#request :(仅在Web Contexts中)HttpServletRequest对象。
#session :(仅在Web上下文中)HttpSession对象。
#servletContext :(仅在Web上下文中)ServletContext对象。
#response:(仅在Web上下文中)HttpServletResponse对象。
#ctx:上下文对象。 根据我们的环境(独立环境或Web环境),实现org.thymeleaf.context.IContext或org.thymeleaf.context.IWebContext。
${#ctx.locale} ${#ctx.variableNames} ${#ctx.request} ${#ctx.response} ${#ctx.session} ${#ctx.servletContext} |
#locale:直接访问与当前请求关联的java.util.Locale。 ${#locale}
...
#request:直接访问与当前请求关联的javax.servlet.http.HttpServletRequest对象。
${#request.getAttribute('foo')}
${#request.getParameter('foo')}
${#request.getContextPath()}
${#request.getRequestName()}
#session:直接访问与当前请求关联的javax.servlet.http.HttpSession对象。
${#session.getAttribute('foo')}
${#session.id}
${#session.lastAccessedTime}
...
#servletContext:直接访问与当前请求关联的javax.servlet.ServletContext对象。
${#servletContext.getAttribute('foo')}
${#servletContext.contextPath}
...
request和session属性的web命名空间
在Web环境中使用Thymeleaf时,我们可以使用一系列快捷方式来访问请求参数,会话属性和应用程序属性:
注意:这些不是上下文对象,而是添加到上下文中的Map集合作为变量,所以我们在没有#的情况下访问它们。 在某种程度上,它们作为命名空间。
param:用于获取请求参数。 $ {param.foo}是一个带有foo请求参数值的String [],所以$ {param.foo [0]}通常用于获取第一个值。
${param.foo} // Retrieves a String[] with the values of request parameter 'foo' ${param.size()} ${param.isEmpty()} ${param.containsKey('foo')} ... |
session:用于获取session属性。
${session.foo}
...
application:用于获取应用程序或servlet上下文属性。
${application.foo}
...
除了这些基本的对象之外,Thymeleaf将为我们提供一组工具对象,这些对象将帮助我们在表达式中执行常见任务。
#execInfo:有关正在处理的模板的信息。
#messages:用于在变量表达式中获取外部化消息的方法,与使用
#{...}语法获得的方式相同,操作消息的工具。
#uris:转义URL / URI部分的方法
#conversions:执行配置的转换服务(如果有的话)的方法。
#dates:java.util.Date对象的方法:格式化,组件提取等
#calendars:类似于#dates,但对于java.util.Calendar对象。
#numbers:用于格式化数字对象的方法。
#strings:String对象的⽅法:contains,startsWith,prepending /appending等
#objects:一般对象的方法,参照java.lang.Object;
#bools:判断布尔类型工具。
#arrays:数组操作的工具;
#lists:列表操作的工具,参照java.util.List;
#sets:Set操作工具,参照java.util.Set;
#maps:Map操作工具,参照java.util.Map;
#aggregates:操作数组或集合的工具;
#ids:处理可能重复的id属性的方法(例如,作为迭代的结果)。
例子:
简单数据转换(数字,日期) 字符串拼接
|
原文:https://blog.csdn.net/malimingwq/article/details/79329921
验证模板的正确性
静态资源引入问题
可直接在static文件夹下的css文件夹和js文件夹引用
也可以设置一个前缀
spring: mvc: static-path-pattern: /static/**
|
引用:
<link th:href="@{/static/css/style.css}" rel="stylesheet" /> <script th:src="@{/static/js/jquery-2.1.4.min.js}">script> |
参考:https://www.jianshu.com/p/3426794a17cb