FreeMarker Thymeleaf - 前端模板引擎

FreeMarker

概述
  • FreeMarker是一种模板引擎(基于模板和要改变的数据),主要用于MVC中的view层,生成html展示数据给客户端,可以完全替代jsp
  • 它不是面向最终用户的,而是一个Java类库,是一款可以嵌入所开发产品的组件,后缀通常是ftl
  • 它是一个基于模板生成文本输出的通用工具,使用纯Java编写,模板中没有业务逻辑,外部java程序通过数据库操作等生成数据传入template中,然后输出页面。它能够生成各种文本:HTML、XML、JSP、RTF、Java源代码等等,而且不需要Servlet环境,并且可以从任何源载入模板,如本地文件、数据库等等
模板文件
  • 注释
    • <#–注释内容–>
  • 文本
    • 生成的文件内容,例如java语句或HTML元素等
  • 插值
    • ${ expr }通用插值
    • #{ expr }或#{expr;format}数字格式化插值
避免空值插值
    !:指定缺失变量的默认值
    ${sss!} <#--没有定义这个变量,默认值是空字符串! -->  
    ${sss!"abc"} <#--没有定义这个变量,默认值是字符串abc! -->  
    ??:判断变量是否存在
    variable??,如果变量存在,返回true,否则返回false。

插值规则
a) 表达式放置在插值语法${}之中,用于输出表达式的值。
b) 表达式的值的类型可以是:字符串、 数字、布尔、日期时间、序列、Hash结构
c) 表达式支持Java中的所有运算符:
     算术运算符:+-*/%
     比较运算符:==(eq)!=(ne)>(gt)>=(gte)<(lt)<=(lte)
     逻辑运算符:&&(and)||(or)!(not)
     三目运算符:? :
d) 内置函数:
    Ⅰ) 使用方式:表达式?函数名[(实参)]) 字符串的常用内置函数: substring(from[, to])、html、length、trim、url 示例:<#setting url_escaping_charset="UTF-8"> 、exp?url[("UTF-8")]) 数字的常用内置函数:c、string[(数字模式串)]、
    Ⅳ) 布尔的内置函数:string[("男", "女")]) 内置的常用日期时间函数:string[("格式模式串")]、datetime、date、time
e) 序列:
在FTL中定义的序列:由方括号包括,各元素用英文逗号分隔如:<#assign seq=["winter", "spring", "summer",  "autumn"]>也可以用数字范围(递增、反递增)定义数字序列: <#assign nums=101..105><#assign nums=105..101> 在数据模型中可以是List对象、Set对象,序列的常用内置函数:size、sort[("指定字段作排序依据")]
f) Hash结构:FTL文件中直接定义时:由大括号包括,由逗号分隔键/值列表,键和值之间用冒号分隔。键必须是字符串。如: <#assign scores={"语文":78, "数学":89, "英语":87}> ${scores.语文} 在数据模型中可以是Map对象,Hash结构的内置函数:size、keys、values
  • FTL指令(FreeMarker指令)

    • assign 指令:用于为该模板页面创建或替换一个顶层变量
    <#--定义变量-->
    <#assign id=1 name="zhangsan" sex="男">
    <#--定义数组-->
    <#assign hobbyArr=['篮球','足球','排球']>
    <#--定义Map集合-->
    <#assign people={"name":"mouse","age":25,"weight":140}>
    
    • if else 指令:用于条件判断
    <#--gt:小于 gte:小于等于-->
    <#assign age=20>
    <#if age gt 60>老年人
    <#elseif age gt 40>中年人
    <#elseif age gt 20>青年人
    <#else> 少年人
    </#if>
    <#if (age==20)>
    我今年20</#if>
    
    • list 指令:迭代List集合
    item_index:当前变量的索引值 
    item_has_next:是否存在下一个对象 
    break:跳出迭代
    <#list 1..9 as i>
        ${i}
    </#list>
    
    <#list hobbyArr as hobby>
        下标:${hobby_index}
        值:${hobby}<br/>
        <#if !hobby_has_next>
            已经是最后一个
            <#break>
        </#if>
     </#list>
     长度:${hobbyArr?size}
    
    <#--迭代Map集合-->
    <#assign keys = people?keys>        <#--map的key集合-->
    <#list keys as key>
        ${key} = ${h[key]}
    </#list>
    
    • switch 指令
    <#assign age=10>
    <#switch age>
        <#case 0>0<#break>
        <#case 10>10<#break>
        <#case 20>20<#break>
        <#default>30
    </#switch>
    
    • include 指令:用于导入文件,它可以在模版中插入其他的静态文件,或者是freemarker模版
    <#--parse=true 是否作为ftl语法解析,默认是true-->
    <#include "inc.ftl" encoding="UTF-8" parse=true>
    
    • import 指令:导入文件,然后就可以在当前文件里使用被导入文件里的宏组件,类似于java里的import
    <#--访问时使用 inc.-->
    <#import "inc.ftl" as inc>
    ${inc.name}
    
    • noparse 指令:指定FreeMarker不处理该指定里包含的内容
使用
  • 定义一个配置对象 参数是 Freemarker的版本
    • Configuration conf=new Configuration(Configuration.VERSION_2_3_28);
  • 设定模板路径
    • conf.setDirectoryForTemplateLoading(new File(“url”));
  • 获取ftl模板对象
    • Template temp = conf.getTemplate(“模板名.ftl”);
  • 为模板添加数据部分
    • Map<String,Object> root=new HashMap<String, Object>();
    • root.put(“数据参数名”, “value”);
  • 设定生成文件路径
    • FileWriter out=new FileWriter(“地址”);
  • 生成目标文件
    • temp.process(root, out);
  • 关闭资源
    • out.flush();
    • out.close();
springmvc整合
<!-- 配置Freemarker属性文件路径 -->  
    <bean id="freemarkerConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">  
        <property name="location" value="classpath:freemarker.properties" />  
    </bean>  
<!-- 配置freeMarker模板加载地址 -->  
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 视图解析器在/tpl/路径下扫描视图文件 -->  
     <property name="templateLoaderPath" value="/tpl/" />  
     <property name="freemarkerVariables">  
        <map>  
            <entry key="xml_escape" value-ref="fmXmlEscape" />  
        </map>  
     </property>  
       <property name="freemarkerSettings">
           <props>
               <!-- 模板编码格式 -->
               <prop key="default_encoding">UTF-8</prop>
               <!-- 本地化设置 -->
               <prop key="locale">UTF-8</prop>
               <!-- url转义编码 -->
               <prop key="url_escaping_charset">UTF-8</prop>
           </props>
       </property>
    </bean>  
    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />  

<!-- 配置freeMarker视图解析器 -->  
    <bean id="freemakerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />  
<!-- 扫描路径內所有以ftl結尾的文件 -->  
        <property name="viewNames">  
            <array>  
                <value>*.ftl</value>  
            </array>  
        </property>
        <!-- 配置逻辑视图自动添加的后缀名 --> 
        <property name="suffix" value=".ftl"/>
        <property name="contentType" value="text/html; charset=UTF-8" />  
        <property name="exposeRequestAttributes" value="true" />
        <!-- 是否在model自动把session中的attribute导入进去; -->
        <property name="exposeSessionAttributes" value="true" />  
        <property name="exposeSpringMacroHelpers" value="true" />  
        <property name="requestContextAttribute" value="request" />  
        <!-- 给视图解析器配置优先級,你可以给之前jsp视图解析器的值配为2 -->  
        <property name="order" value="1" />  
</bean>
内建函数
  • 通过?调用内置函数传参数
// string表示转换为string类型函数 参数是日期格式化参数
${参数?string("yyyy-MM-dd HH:mm:ss")}

Thymeleaf

概述

  • Thymeleaf 是一种模板语言,包括数据(Data)、模板(Template)、模板引擎(Template Engine)和结果文档(Result Documents),可以完全替代 JSP
  • 是SpringBoot推荐的模板引擎,语法更加接近HTML即使用html的标签来完成逻辑和数据的传入进行渲染
  • 与其它模板引擎相比, Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用
  • 支持SpEL,SpEL是可以用于Spring中的一种EL表达式
  • 特点
    • Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示
    • Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言
    • Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能

使用

  • 1.导入thymeleaf-2.1.4.RELEASE.jar
// maven依赖
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>2.1.4</version>
</dependency>
  • 2.HTML增加头文件
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
  • 3.用th标签动态替换掉静态数据
<!-- 将后台传来的message显示,静态文件则显示thymeleaf -->
<td th:text="${message}">thymeleaf</td>
整合spring
  • 导入thymeleaf-spring4-2.1.4.RELEASE.jar
// maven依赖
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring3</artifactId>
    <version>2.1.4</version>
</dependency>
  • SpringMVC配置文件
<context:component-scan base-package="com.test.thymeleaf.controller" />
<mvc:annotation-driven />
<!--springMVC+thymeleaf的跳转页面配置-->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
  <property name="prefix" value="/WEB-INF/views/" />
  <property name="suffix" value=".html" />
  <property name="templateMode" value="HTML5" />
</bean>

<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
	<property name="templateResolver" ref="templateResolver" />
</bean>

<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
	<property name="templateEngine" ref="templateEngine" />
</bean>

用法

标签属性(存在优先级)
  • 片段包含
    • th:fragment //定义待引用的模块
    <div th:fragment="footer">
    
    • th:insert //引用其他模块,保留自己的主标签,保留th:fragment的主标签
    <div th:insert="test :: footer"></div>
    
    • th:replace //引用其他模块,保留自己的主标签,不保留th:fragment的主标签
    <div th:include="test::footer">test</div>
    
    • th:replace //引用其他模块,不保留自己的主标签,保留th:fragment的主标签,Thymeleaf 3.0不再推荐使用
    <div th:replace="test::footer">test</div>
    
  • 遍历
    • th:each //用于遍历集合中的对象,相当于jstl中的<c:forEach>标签
    <tr th:each="user,userStat:${messages.list}">
    	<td th:text="${user.name}"></td>
    	<td th:text="userStat.index"></td>
    </tr>
    // user是临时变量,userStat称为状态变量
    // 状态变量属性有:
    		index:当前迭代对象的迭代索引,从0开始,这是索引属性;
    		count:当前迭代对象的迭代索引,从1开始,这个是统计属性;
    		size:迭代变量元素的总量,这是被迭代对象的大小属性;
    		current:当前迭代变量;
    		even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算);
    		first:布尔值,当前循环是否是第一个;
    		last:布尔值,当前循环是否是最后一个;
    
  • 条件判断
    • th:if //用于判断条件,还可以多条件 and,or(二元操作符),!,not非(一元操作符)
    <span th:if="${product.price lt 100}" class="offer">Special offer!</span>
    // 不能用"<”,">"等符号,要用"lt"等替代
    
    • th:unless //用于判断条件,与th:if作用相反
    • th:switch th:case //用于多个同等级相同目的判断,多选一时使用
    <div th:switch="${user.name}">
    	// 若${user.name}中的值为maliming则显示,否则不显示
    	<p th:case="maliming">first</p>
    	<p th:case="${otherUser.name}">second</p>
    </div>
    
  • 声明变量
    • th:object //用于表单数据对象绑定,后台controller中参数保持一致,和选择(星号)表达式
    <form th:object="${user}">
    	<input th:value="*{name}"/>  //*号代替了${user}
    </form>
    
    • th:with
  • 修改任意属性
    • th:attr //用于设置任意属性
    <input th:attr="value=${user.name}"/> 设置单个属性
    <input th:attr="value=${user.username},name=username,style='background-size:cover;'"/> 设置多个属性之间用逗号隔开
    
  • 修改指定属性默认值即替换原生属性的值 //th:任意html属性
    • th:value //用于属性赋值
    <option th:value="${user.name}"></option>
    
    • th:src //用于外部资源的引入,例如图片,js文件
    <img th:src="@{../images/myself.jpg}"/>或<script th:src="@{../static/login.js}">
    </script>
    
    • th:href //用于定义超链接,相当于<a>标签的href属性
    <a th:href="@{/user/selectUser?(currentPage=1,reTypeid=${reTypeid},inquiry=${inquiry})}"></a>
    
    • th:selected //用于选择框设置选中值。通常和th:each一起使用
    <select οnchange="getChilds(this.value)" id="catId">
    	<option   th:each="c:${categoryList}"  th:selected="${goods.catId eq c.id}" th:value="${c.id}" th:text="${c.name}" value="1">蔬菜</option>
    </select>
    
    • th:action //用于定义后台控制器的路径,表单的提交地址,相当于标签的action属性
    <form th:action="@{user/login}" method="post"></form>
    
  • 修改标签体内容
    • th:text //用于文本的显示,并且可以进行简单的计算,会转义文本中的特殊字符,使效果不显示
    • th:utext //用于文本的显示,常用于富文本编辑器编辑后的内容显示到前台页面上
  • 移除片段
    • th:remove //用于删除。可用表达式传参
      • all:删除所在标签和内容及其所属的所有子标签。
      • body:删除所在标签的内容及其所属的所有子标签。
      • tag:删除所在标签,不删除任何所属的子标签。
      • all-but-first:删除除第一个子标签外的其他子标签。
      • none:不起作用,什么也不做
    <tbody th:remove="all-but-first">
    	//用count进行统计,有顺序的显示
    	<tr th:each="product:${productList}">
    		<td th:text="${productStat.count}">1</td>
    		<td th:text="${product.description}">Red Chair</td>
    	</tr>
    	<tr>
    		<td>1</td>
    		<td>White table</td>
    	<tr>
    </tbody>
    
  • 其他
    • th:block //只允许模板开发人员指定他们想要的属性的属性容器,唯一的一个Thymeleaf块级元素,Thymeleaf模板引擎在处理 th:block 的时候会删掉它本身,标签本身不显示,而保留其内容
    <table>
    	<th:block th:each="user : ${users}">
    		<tr>
    			<td th:text="${user.login}">...</td>
    			<td th:text="${user.name}">...</td>
    		</tr>
    		<tr>
    			<td colspan="2" th:text="${user.address}">...</td>
    		</tr>
    	</th:block>
    </table>
    
    • th:inline
      • Thymeleaf模板中的三个模板被认为是文本:TEXT,JAVASCRIPT和CSS,标记模板模式:HTML和XML
      • 区别:在文本模板中,没有标签,以属性的形式插⼊逻辑,因此我们必须依赖其他机制。最基本的机制是内联, 内联语法是以文本模板模式输出表达式结果的最简单方法
      • 内联文本:
      <p th:inline="text">Hello, [[#{test}]]</p>
      
      • 内联JavaScript:
      <script th:inline="javascript">var username = [[${session.user.name}]];</script>
      
      • 内联CSS
      <style th:inline="css">
      	 .[[${classname}]] {
      	  	text-align: [[${align}]];
      	  }
      </style>
      //输出为
      <style th:inline="css">
      	.main\ elems {
      		text-align: center;
      	}
      </style>
      
表达式
  • 变量表达式:${…}
// 引用user对象的name属性值,未获取则为tom
<input type="text" value="tom" th:value="${user.name}" />
// 字符串拼接
<div th:text="${'$'+product.price}">888</div>
  • 选择表达式:*{…}
// 一般跟在th:object后,直接取object中的属性
<div th:object="${session.user}">
     <p>user: <span th:text="*{firstName}">tom</span></p>    
</div>
// 等同于
<div>
     <p>user: <span th:text="${session.user.firstName}">tom</span></p>    
</div>
  • 文字国际化表达式:#{}
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>

调用国际化的welcome语句,国际化资源文件如下
resource_en_US.properties:home.welcome=Welcome to here!
resource_zh_CN.properties:home.welcome=欢迎您的到来!
  • 链接网址表达式:@ {}
<img src="当前路径" th:src="@{${后台传来路径}}" /> 
  • 片段表达式:〜{}
// 导入模块片段,常与th:insert或th:replace搭配进行片段插入
<div th:insert="~{commons :: main}">...</div>
// 可在任何地方使用,就像任何其他变量一样
<div th:with="frag=~{footer :: #main/text()}">
	<p th:insert="${frag}">
</div>
表达式内置对象
  • #ctx:上下文对象
  • #locale:上下文区域设置
  • #vars:上下文变量
  • #request :(仅在Web Contexts中)HttpServletRequest对象
  • #session :(仅在Web上下文中)HttpSession对象
  • #servletContext :(仅在Web上下文中)ServletContext对象
  • #response:(仅在Web上下文中)HttpServletResponse对象
  • #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属性的方法(例如,作为迭代的结果)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值