谨以此文献给那些将要从 Velocity 跳到 Thymeleaf 这个坑的人。
提到 Thymeleaf,想必大家对这个名字比较陌生,如果是在几天前我也是闻所未闻。然而,大佬突然一声令下:「我们要把仓储管理系统分离出去,用 Spring Boot 进行开发。」相伴而来的就是后端模板引擎的变更——不再支持 Velocity 了!
在接到这个消息后,第一时间到官网看下这首次听到的东西长个啥样。乍一看,觉得咋那么眼熟呢?哦~原来是跟 Vue 有点像!
先来瞅一瞅 Vue 的模板语法——
再看看 Thymeleaf——
我去!难道它们是失散多年的双胞胎?!
本文并非 Thymeleaf 使用教程,而是讲述如何以尽可能小的改动将页面从 Velocity 迁移到 Thymeleaf。若想了解 Thymeleaf 的用法,请看官方文档。
Spring MVC + Velocity
目前大部分项目是 Spring MVC + Velocity,但以后的新项目很可能都是 Spring Boot + Thymeleaf。不管怎么说,还是先看下 Velocity 中的模板用法吧。
布局模板
在我所参与的项目中,layout 的模板代码大概是这样的——
其中所使用的变量都是具体页面中定义的,有的是用 #set()
定义的简单的值:
变量名 | 含义 | 是否必须 |
primaryPage | 一级页面标记 | 是 |
secondaryPage | 二级页面标记 | 是 |
pageTitle | 当前页面标题 | 是 |
有的是用 #define()
定义的代码片段:
变量名 | 含义 | 是否必须 |
headAssets | 各页面样式 | 否 |
headerActions | 页头中的操作 | 否 |
breadcrumb | 面包屑 | 是 |
queryArea | 条件筛选区域 | 否 |
dataTableList | 数据表格 | 否 |
modal | 新增/修改数据对话框 | 否 |
bodyAssets | 各页面脚本 | 否 |
页面模板
每个具体页面的模板中所写的代码,除了在 layout 中指定位置引用的 #define()
定义的片段会显示在相应的位置,其他的不在 #define()
中的代码都会被渲染到 $screen_content
的位置——
Spring Boot + Thymeleaf
虽然 Themeleaf 的语法比较「友好」,但完全靠自己去把原来用 Velocity 写的页面完全成功迁移过来,至少得用半天到一天的时间去踩坑探索。但有了这篇文章就不一样了,看完之后基本不用去看官方文档就能够完成!
不管怎么说,Thymeleaf 的模板语法还是要先叨咕叨咕的。
模板语法
虽然说的时候只说「Thymeleaf」,但在实际使用时却是 Thymeleaf 和 Thymeleaf Layout Dialect。前者提供核心功能,其语法为 th:*
;后者专解决布局及模板继承问题,语法是 layout:*
。本文中所用示例是基于 Thymeleaf 2.x 和 Thymeleaf Layout Dialog 1.x 实现,有的用法在新版本中可能已不被支持。
在迁移的过程中,主要用到的语法如下:
语法 | 作用 |
layout:decorator | 指定所继承的布局模板 |
layout:fragment | 定义用于布局的代码片段 |
th:fragment | 定义通用的非布局代码片段 |
th:replace | 用指定片断替换当前元素 |
th:with | 向代码片段中传入参数 |
th:if | 条件判断 |
th:each | 遍历 |
th:text | 覆盖文本 |
在访问变量时要用 ${variable}
形式,文件路径用 @{/path/to/your/file}
的形式。另外,Thymeleaf 中提供了一个不被渲染的可用作占位符的虚拟元素——<th:block>
。
在了解了这些语法之后,就可以开展迁移工作了!
布局模板
用上面所介绍的语法,将 Velocity 的 layout 改造为——
如果细心观察就会发现,迁移后与迁移前相比,少了 headAssets 变量并多了个 creatable 变量。
去掉了 headAssets
是因为 Thymeleaf Layout Dialect 提供了一种机制,可以将具体页面模板的 <head>
标签中的 <link>
和 <script>
自动插入到布局模板的 <head>
标签的底部,即闭合标签 </head>
前。
增加了 creatable
则是因为 Thymeleaf 中无法对某个代码片段判断是否存在。(也许是我不会……)
页面模板
只要布局模板的继承及排列逻辑搞定了,具体页面模板的迁移就小菜一碟儿了~
后语
重要的部分都已经说完了,但在迁移过程中有几点需要注意的,否则 Thymeleaf 在解析时会报错:
<img>
、<input>
这类单标签需要有斜杠关闭标签:<img />
、<input />
; required
、multiple
等属性需要有值:required="required"
、multiple="multiple"
。
至此,本文已接近尾声,如果你在看过之后茅塞顿开,那我这就是一篇成功的文章!
创作不易,若本文给你提供了价值,还请不吝为欧雷充电
左为微信,右为支付宝;充电累计 ¥88 以上可在付款时备注或邮件告知昵称和需要被链接的网址,会列在「赞助」页。其他方式与具体规则请见「资助」。