任何一种语言,都有其语法约束,前端模板引擎也不例外。本文将介绍Thymeleaf方言中最重要的部分之一:标准表达式语法。
标准表达式语法的基本内容如下。
- 简单表达式
- 变量表达式:${...}
- 选择变量表达式:*{...}
- 信息表达式:#{...}
- 链接URL表达式:@{...}
- 片段表达式:~{...}
- 常量
- 文本常量:'example','other example',...
- 号码常量:1,12, 5.0,12.56,...
- 布尔常量:true,false
- 空常量:null
- 常量标记:one,sometext,other,...
- 文本操作
- 字符串串联:+
- 文字替换:|hello,my name is ${name}|
- 算术运算
- 二元运算符:+,-,*,/,%
- 减号(一元运算符):-
- 布尔运算
- 二元运算符:and,or
- 布尔否定(一元运算符):!,not
- 比较和相等
- 比较运算:>,<,>=,<=,(gt,lt,ge,le)
- 相等运算(一元运算符):==,!=,(eq,ne)
- 条件运算符
- If-then:(if) ? (then)
- If-then-else:(if) ? (then) : (else)
- Default:(value) ?: (defaultvalue)
- 特殊令牌
- 无操作:_
所有这些特性均可进行组合和嵌套:
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
信息
信息表达式 #{} 用于展示静态资源的内容,比如i18n属性配置文件。
<
新建/static/templates/home.properties,其中home.welcome=this messages is from home.properties!。那么,信息表达式解析后为:
<
如果信息文本不完全是静态的怎么办?例如,如果我们的应用程序知道谁是随时访问该网站的用户并且我们想要通过名字问候他们怎么办?
<
我们可以在信息中添加一个参数:
home.welcome=¡Bienvenido a nuestra tienda de comestibles, {0}!
参数是根据java.text.MessageFormat标准语法指定的,这意味着可以格式化为java.text.*包中的类的API文档中指定的数字和日期。
假定给定HTTP会话属性user:
<
请注意,使用th:utext此处意味着格式化的消息不会被转义。此示例假定user.name已经转义。
也可以指定几个参数,以逗号分隔。
信息键值也可以来自于变量:
<
更复杂的例子(预处理)
此例结合了信息表达式、变量表达式、预处理表达式,如看不懂,可选择跳过,待后续表达式语法学习完毕后,可回过来头再看。
#{home.__${sel.code}__}
该表达式解析,实际上可以分解为3步:
- 先计算变量${sel.code},假如值是welcome
- __的含义是需要预处理的变量值,那么就变成#{home.welcome}
- 计算最终结果
变量
变量表达式 ${...} 实际上是把上下文中包含的变量映射到OGNL表达式,即在SpringMVC中的模型属性,如:${user.name}。可直接使用 th:xx = "${...}" 获取对象属性,如定义在属性中:<span th:text="${book.author.name}">、遍历:<li th:each="book : ${books}">。
从ognl的语法,表达式:
<
实际上相当于:
ctx
但是OGNL允许我们创建功能更强大的表达式,即这种方式:
<
等价于:
((
但是,getter方法导航只是OGNL的功能之一。还有更多:
/*
表达式基本对象
在上下文变量中评估OGNL表达式时,某些对象可用于表达式,以提高灵活性。这些对象(OGNL标准)将以 # 符号开头进行引用:
- #ctx:上下文对象。
- #vars: 上下文变量。
- #locale:上下文语言环境。
- #request:(仅在Web上下文中)HttpServletRequest 对象。
- #response:(仅在Web上下文中)HttpServletResponse 对象。
- #session:(仅在Web上下文中)HttpSession 对象。
- #servletContext:(仅在Web上下文中)ServletContext 对象。
因此,我们可以这样做:
<
完整的表达式基本对象请参见附录1。
表达式实用对象
除了基本对象之外,Thymeleaf还为我们提供一组实用对象,这些对象将帮助我们在表达式中执行常见任务。
- #execInfo:正在处理的模板的信息。
- #messages:用于获取变量表达式内的外部化消息的方法,与使用#{…} 语法获得消息的方法相同。
- #uris:用于转义部分 URL / URI 的方法
- #conversions:用于执行已配置的转换服务(如果有)的方法。
- #dates:java.util.Date 对象的方法:格式化,组件提取等。
- #calendars:与 #dates 类似,用于 java.util.Calendar 对象。
- #numbers:格式化数字的方法。
- #strings:String对象的方法:包含,startsWith,prepending/appending等。
- #objects:一般对象的方法。
- #bools:布尔值评估的方法。
- #arrays:数组方法。
- #lists:列表方法。
- #sets:set集合方法。
- #maps:map方法。
- #aggregates:用于在数组或集合上创建聚合的方法。
- #ids:用于处理可能重复的id属性的方法(例如,由于迭代的结果)。
具体每个实用对象的功能,可以参见附录2。
用一下
格式化日期:
<
非空判断:
<
怎么样,方便吧!
附录1:表达式基础对象
基础对象
- #ctx:上下文对象。实现了 org.thymeleaf.context.IContext 或 org.thymeleaf.context.IWebContext 接口,取决于我们的环境(单机或网络)。
注意,与 #vars 和 #root 是同一个对象,但建议使用 #ctx。
/*
- #locale:访问 java.util.Locale 与当前请求关联的内容。
$
请求/会话属性等的Web上下文名称空间
在Web环境中使用Thymeleaf时,我们可以使用一系列快捷方式来访问请求参数,会话属性和应用程序属性:
请注意,这些不是上下文对象,而是作为变量添加到上下文中的映射,因此我们不使用 # 即可访问它们。在某种程度上,它们充当命名空间。
- param:用于检索请求参数。${param.foo} 是 String[] 类型的foo request参数的值数组,因此${param.foo[0]}通常用于获取第一个值。
/*
- session : 用于检索会话属性。
/*
- application 用于检索应用程序/ servlet上下文属性。
/*
请注意,无需指定用于访问请求属性的名称空间(与request参数相对),因为所有请求属性都作为变量自动添加到上下文根目录中:
$
Web上下文对象
在Web环境中,还可以直接访问以下对象(请注意,这些是对象,而不是映射/命名空间):
- #request:直接访问 javax.servlet.http.HttpServletRequest 与当前请求关联的对象。
$
- #session:直接访问 javax.servlet.http.HttpSession 与当前请求关联的对象。
$
- #servletContext:直接访问 javax.servlet.ServletContext 与当前请求关联的对象。
$
附录2:表达式实用对象
Execution Info
- #execInfo:提供有关Thymeleaf标准表达式中正在处理的模板的有用信息的表达式对象。
/*
Messages
- #messages:用于获取变量表达式内的外部化消息的实用程序方法,与使用 #{...} 语法获得消息的方式相同。
/*
URI / URL
- #uris:在Thymeleaf标准表达式内执行URI / URL操作(尤其是转义/转义)的实用程序对象。
/*
conversions
- #conversions:允许在模板的任何位置执行转换服务的实用程序对象。
/*
dates
- #dates:java.util.Date 对象的实用程序方法。
/*
calendars
- #calendars:与 #dates 类似,但基于 java.util.Calendar 对象。
/*
numbers
- #numbers:用于数字对象的实用方法。
/*
strings
- #strings:String 对象的实用方法。
/*
objects
- #objects:一般对象的实用方法。
/*
bools
- #bools:用于布尔值评估的实用方法。
/*
arrays
- #arrays:数组的实用方法
/*
lists
- #lists:列表的实用方法。
/*
sets
- #sets:集合的实用方法。
/*
maps
- #maps:地图的实用方法。
/*
aggregates
- #aggregates:在数组或集合上创建聚合的实用程序方法。
/*
ids
- #ids:用于处理 id 可能重复(例如,由于迭代的结果)的属性的实用方法。
/*
我是银河架构师,十年饮冰,难凉热血。愿历尽千帆,归来仍是少年!
如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!
文章不定时更新,可微信搜索「银河架构师」,精彩内容,先睹为快!