freemark的常用方法
1,截取字符串
有的时候我们在页面中不需要显示那么长的字符串,比如新闻标题,这样用下面的例子就可以自定义显示的长度
< lt. <= lte. > gt. >= gte
<#if jstbqkVO.gzdd?length lt 8>
<a href>${jstbqkVO.gzdd?default("")}</a>
<#else>
<a href title="${jstbqkVO.gzdd}">${jstbqkVO.gzdd[0..3]?default("")}...</a>
</#if>
意思就是如果这个字符串的长度小于8,那么就正常显示,反之则取4位
2.连接字符串
${"Hello," + user + "!"} //输出结果为:hello,gs!
3,日期格式和boolean 类型,转化为string类型
例子2:
${lastUpdate?string("yyyy-MM-dd HH:mm:ss zzzz")}
${lastUpdate?string("EEE,MMM d, ''yy")}
${.................("EEEE,MMM dd,yyyy, hh:mm:ss a '('zzz')'")}
输出结果如下:
2003-04-08 21:24:44 Pacific Daylight Time
Tue,Apr 8,'03
Tuesday,April 08,2003,09:24:44 PM (PDT)
例子3:
<#assign foo=true/>
${foo?string("yes","no")} //输出结果:yes
4,排序:
1.升序.sort_by()
<#list list?sort_by("字段") as x>
</#list>
2.降序.sort_by()?reverse
<#list list?sort_by("字段")?reverse as x>
</#list>
5去空格:
${xx?trim}
6数值精度控制
mX:小数部分最小X位。
MX:小数部分最大X位。
例子:
<#assign x=2.582/>
<#assign y=4/>
#{x; M2} //2.58
#{y; M2} //4
#{x; m1M2} //2.58
#{y; m1M2} //4.0
7特殊字符串的转义
\":双引号 \\:反斜杠 \r:回车 \b:退格键
\':单引号 \n:换行 \t:Tab \f:Form feed
\l:< \g:> \a:& \{:{
\xCode:直接通过4位的十六进制数来指定Unicode码
,输出改Unicode对应的字符。
8.顶层变量
* 所谓顶层变量就是直接放在数据模型中的值。
Map root = new HashMap();
root.put("name","yeeku"); //name是一个顶层对象
* 对于顶层变量,直接使用${variableName}来输出变量值
9.集合连接运算符
* 集合连接运算是将两个集合连接成一个新的集合,连接集合的运算符是'+'.
<#list ["一","二","三"] + ["四","五","六"] as x>
${x}
</#list>
//输出结果如下:
一二三四五六
10 算术运算符
* 取整运算
<#assign x=5>
${(x/2)?>int} //2
${1.1?int} //1
${1.999?int} //1
${-1.1?int} //-1
11 比较运算符
=(==) :判断两个值是否相等
!= :............不相等
>(gt) :判断左边是否大于右边
>=(gte) :.....
<(lt) :.....
<=(lte) :.....
12 逻辑运算符
* 逻辑运算符只能作用于布尔值,否则将产生错误.
逻辑与:&&
逻辑或:||
逻辑非:!
13 内置函数
html:字符串中所有的特殊HTML字符都需要用实体引用来代替(比如<代替<)
cap_first:字符串的第一个字母变为大写形式
lower_case:字符串的小写形式
upper_case:字符串的大写形式
trim:去掉字符串首尾的空格
序列使用的内建函数:
size:序列中元素的个数
数字使用的内建函数:
int:数字的整数部分(比如-1.9?int就是-1)9>.空值运算符
length:字符串的长度
string :把其他格式的数据,转化为string类型
例:
${test?html}
${test?upper_case?html}
假设字符串test存储”Tom & Jerry”,那么输出为:
Tom & Jerry
TOM & JERRY
${seasons?size}
${seasons[1]?cap_first}
${"horse"?cap_first}
假设seasons存储了序列"winter", "spring", "summer", "autumn",那么上面的输出将会是:
4
Spring
Horse
14.运算符优先级
* 推荐使用括号来决定运算优先级.
1>.一元运算符: !
2>.内建函数 : ?
3>.乘除法 : *,/,%
4>.加减法 : +,-
5>.比较 : <,>,<=,>=(lt,lte,gt,gte)
6>.相等 : ==(=),!=
7>.逻辑与 : &&
8>.逻辑或 : ||
9>.数字范围 : ..
15,freemarker判断返回值是否为空,null的方法
对于null,或者miss value,freemarker会报错
!:default value operator,语法结构为:unsafe_expr!default_expr,比如 ${mouse!"No mouse."} 当mouse不存在时,返回default value;
(product.color)!"red" 这种方式,能够处理product或者color为miss value的情况;
而product.color!"red"将只处理color为miss value的情况
??: Missing value test operator ,测试是否为missing value
unsafe_expr?? :product.color??将只测试color是否为null
(unsafe_expr)??:(product.color)??将测试product和color是否存在null
?exists:旧版本的用法
比如:<#if mouse??>
Mouse found
<#else>
No mouse found
</#if>
Creating mouse...
<#assign mouse = "Jerry">
<#if mouse??>
Mouse found
<#else>
No mouse found
</#if>
FreeMarker的常用指令
1>.if指令
<#if condifition>
...
<#elseif condifition>
...
<#else>
...
</#if>
2>.switch、case、default、break指令
<#switch value>
<#case refValue1>
...
<#break>
<#case refValue2>
...
<#break>
<#default>
...
</#switch>
3>.list、break指令
<#list sequence as item>
...
</#list>
* item_index :当前变量的索引值.
* item_has_next :是否存在下一个对象.
例子:
<#list ["星期一","星期二","星期三","星期四","星期五","星期六"] as x>
${x_index + 1}.${x}
<#if x_has_next>,</#if>
<#if x="星期四"><#break></#if>
</#list>
输出结果:
1.星期一,
2.星期二,
3.星期三,
4.兴趣四,
4>.include指令
:用于指定包含指定页面.
<#include filename [options]>
* filename: 该参数指定被包含的模板文件.
* options : 该参数可以被省略,指定包含时的选项,包含encoding和parase两个选项.
5>.import指令
<#import path as mapObject>
* path :指定要被导入的模板文件.
* mapObject :是一个Map对象.
意思:将path路径中的变量都放在mapObject中.
例子:<#import "/lib/common.ftl" as com>
6>.noparser指令
noparse指令指定FreeMarker不处理该指令里包含的内容.
<#noparse>...</#noparse>
7>.escape指令
* escape:该指令导致body区的插值都会被自动加上escape表达式.
* escape指令解析模板时起作用,而不是在运行时起作用.
* escape指令也嵌套使用,子escape继承父escape的规则.
* 如果需要指定某些插值无需添加escape表达式,则应该使用noescape指令.
<#escape identifier as expression>
...
<#noescape>...</#noescape>
...
</#escape>
8>.assign指令
* 它用于为该模板页面创建或替换一个(顶层)或多个变量.
第一种用法:<#assign name="value" [in namespacehash]>
in子句用于将创建的name变量放入namespacehash命名空间中.
第二种用法:<#assign name1=value1 name2=value2 ... nameN=valueN[in namespacehash]>
第三种用法: 是指将assign指令的内容赋值给name变量.
<#assign name [in namespacehash]>
capture this
</#assign>
例子:
<#assign x>
<#list ["一","二","三"] as n>
${n}
</#list>
</#assign>
${x}
补充.global指令,全局变量赋值
9>.setting指令
:该指令用于设置FreeMarker的运行环境.
<#setting name=value>
name的取值范围如下:
locale:该指令指定该模板所使用的国家语言/语言选项.
number_format:该指令指定格式化输出数字的选项.
boolean_format:该指令指令两个布尔值的语法格式,默认值是"false".
date_format、time_format、datetime_format:格式化输出日期的格式.
time_zone: 设置格式化输出日期时所使用的时区.
10>.macro、nested、return指令
宏和变换器变量是两种不同类型的用户自定义指令,他们的区别是:
宏可以在模板中用macro指令来定义
变换器是在模板外由程序定义
1、宏:和某个变量关联的模板片段,以便在模板中通过用户自定义指令使用该变量
1-1、基本用法:
例如:
<#macro greet>
<font size="+2"> Hello JOE!</font>
</#macro>
使用时:
<@greet></@greet>
如果没有体内容也可以用
<@greet />
1-2、变量:
1)、可以在宏定义之后定义参数,宏参数是局部变量,只在宏定义中有效。如:
<#macro greet person>
<font size="+2"> Hello ${person}!</font>
</#macro>
使用时:
<@greet person="emma"> and <@greet person="LEO">
输出为:
<font size="+2"> Hello emma!</font>
<font size="+2"> Hello LEO!</font>
注意:宏的参数是FTL表达式,所以,person=emma和上面的例子中具有不同的意义,这意味着将变量emma的值传给person,这个值可能是任意一种数据类型,甚至是一个复杂的表达式。
宏可以有多个参数,使用时参数的次序是无关的,但是只能使用宏中定义的参数,并且对所有参数赋值。如:
<#macro greet person color>
<font size="+2" color="${color}"> Hello ${person}!</font>
</#macro>
使用时:
<@greet color="black" person="emma" />正确
<@greet person="emma" />错误,color没有赋值,此时,如果在定义宏时为color定义缺省值<#macro greet person color="black">这样的话,这个使用方法就是正确的。
<@greet color="black" person="emma" bgcolor="yellow" />错误,宏greet定义中未指定bgcolor这个参数
11>自定义函数的使用
. 编写函数
package com.freemarker.test; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import freemarker.template.TemplateMethodModel; import freemarker.template.TemplateModelException; public class SqlGetSysdateMethod implements TemplateMethodModel { public Object exec( List args ) throws TemplateModelException { //得到函数第一个参数,得到的字符串两头会有引号,所以replace String datePattern=(args.get( 0 ).toString()).replace( , ); Date date = new Date(); SimpleDateFormat sdf =new SimpleDateFormat(datePattern); return sdf.format( date ); } }
2.注册与使用
有两种方式:
(1).在模板文件中注册,在模板中使用
<#assign getSysdate= package com.freemarker.test.SqlGetSysdateMethod?new()>
<#assign curdate= getSysdate(yyyy-MM-ddt)/>
(2).处理模板文件时注册关键代码:
Map<String,Object> root=new HashMap<String, Object>();
root.put(getSysdate, new StringLengthMethod());
Configuration config=new Configuration();
File file=new File(templatePath);
//并加载模板文件
config.setDirectoryForTemplateLoading(file);
//设置包装器,并将对象包装为数据模型
config.setObjectWrapper(new DefaultObjectWrapper());
//获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致
Template template=config.getTemplate(templateName,templateEncoding);
//合并数据模型与模板
template.process(root, out);
12>使用宏写一个简单的分页实例
<#macro pagination totalCount pageSize>
<#--声明一个函数transform 转换uri,在新的uri上pager_offset参数 -->
<#assign transform = "util.TransformURI"?new()>
<#--声明一个函数,得到当前页码-->
<#assign pagerOffset = "util.PagerOffset"?new()>
<#--声明一个函数,根据传入的totalCount,pageSize得到总页数-->
<#assign pagerCount = "util.PageCount"?new()>
<#assign pageCount=pagerCount(totalCount,pageSize)>
<#--得到当前的URI和请求参数,得到当前的页码-->
<#if request.queryString?exists>
<#assign uri=request.requestURI+"?"+request.queryString>
<#assign pageIndex=pagerOffset(uri)>
<#assign new_uri=transform(uri)>
<#else>
<#assign uri=request.requestURI>
<#assign pageIndex=pagerOffset(uri)>
<#assign new_uri=transform(uri)>
</#if>
<#if (pageIndex>pageCount)>
<#assign pageIndex=pageCount>
</#if>
<#if (pageIndex>1)>
<a href="${new_uri+1}" title="首页"><<</a>
</#if>
<#--如果前面页数过多,显示"..."-->
<#if (pageIndex>5)>
<#assign prevPages=pageIndex-9>
<#if prevPages lt 1>
<#assign prevPages=1>
</#if>
<#assign start=pageIndex-4>
<a href="${new_uri+prevPages}" title="向前5页">...</a>
<#else>
<#assign start=1>
</#if>
<#-- 显示当前页附近的页-->
<#assign end=pageIndex+4>
<#if (end>pageCount)>
<#assign end=pageCount>
</#if>
<#list start..end as index>
<#if pageIndex==index>
<b>${index}</b>
<#else>
<a href="${new_uri+index}">${index}</a>
</#if>
</#list>
<#--如果后面页数过多,显示"...":-->
<#if (end lt pageCount)>
<#assign endend=end+5>
<#if (end>pageCount)>
<#assign end=pageCount>
</#if>
<a href="${new_uri+end}" title="向后5页">...</a>
</#if>
<#-- 显示"下一页":-->
<#if (pageIndex lt pageCount)>
<a href="${new_uri+pageCount}" title="末页">>></a>
</#if>
</#macro>
自定义了三个方法:
PageCount.java
package util;
import java.util.List;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
* 根据传入的参数,计算出所有的页数
* @author legolas
*/
public class PageCount implements TemplateMethodModel {
@Override
public Object exec(List args) throws TemplateModelException {
Integer totalCount = 0;
Integer pageSize = 0;
try {
totalCount = Integer.parseInt((String) args.get(0));
pageSize = Integer.parseInt((String) args.get(1));
} catch (NumberFormatException e) {
throw new TemplateModelException("请输入正确的总记录数和页面记录数");
}
Integer pageCount = totalCount / pageSize
+ (totalCount % pageSize == 0 ? 0 : 1);
return pageCount;
}
}
TransformURI.java
package util;
import java.util.List;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
* 根据传入的uri,在uri后面加上分页参数
* @author legolas
*
*/
public class TransformURI implements TemplateMethodModel{
@Override
public Object exec(List args) throws TemplateModelException {
String uri = (String) args.get(0);
int n = uri.lastIndexOf("?");
if (n == -1) {
return uri + "?pager_offset=";
}
if (uri.lastIndexOf("?pager_offset") != -1) {
uri = uri.substring(0, uri.lastIndexOf("=") + 1);
return uri;
}
String queryString = uri.substring(n + 1, uri.length());
String suburi = uri.substring(0, n + 1);
String[] strings = queryString.split("&");
for (int i = 0; i < strings.length; i++) {
if (strings[i].startsWith("pager_offset")) {
continue;
}
suburi += strings[i];
suburi += "&pager_offset=";
}
return suburi;
}
}
PagerOffset.java
package util;
import java.util.List;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
* 得到当前的页码
* @author legolas
*
*/
public class PagerOffset implements TemplateMethodModel {
@Override
public Object exec(List args) throws TemplateModelException {
String uri = (String) args.get(0);
String[] string = uri.split("pager_offset=");
if (string.length == 1) {
return 1;
} else {
Integer pager_offset = 1;
try {
pager_offset = Integer.parseInt(string[1]);
} catch (NumberFormatException e) {
pager_offset = 1;
}
return pager_offset;
}
}
}
7>.关于在FreeMarker中使用Struts2标签
* FreeMarker作为视图组件是由Servlet负责加载该模板,并使用数据模型填充该模板,并且将填充后
的标准HTML响应输出给浏览者.
* 在Struts2框架的支持下,Struts2框架充当了之前的Servlet角色.
* 为了使所有的用户请求都经过Struts2框架处理,我们将所有的FreeMarker模板放在WEB-INF/ftl路径下.
* 放在WEB-INF/路径下可以提供更好的安全性,因为Web容器会保证浏览者无法访问到WEB-INF/路径下的资源.
8>.解析模板中的变量
* Struts2解析FreeMarker模板中变量的顺序如下:
1>.FreeMarker模板内建的变量
2>.ValueStack中的变量.
3>.ActionContext中的变量.
4>.HttpServletRequest范围的属性.
5>.HttpSession范围的属性.
6>.ServletContext范围的属性.
* FreeMarker模板的内建变量如下:
stack:代表ValueStack本身,可这样访问其中变量:${stack.findString('ognl expr')}
action:代表刚刚执行过的Action实例.
response:代表HttpServletResponse实例.
request:代表HttpServletRequest实例.
res:代表HttpServletRequest实例.
session:代表HttpSession实例.
application:代表ServletContext实例.
base:代表用户请求的上下文路径.
9>.访问Servlet/JSp范围对象
1.访问Application范围内的属性.
<#if Application.attributeName?exists>
${Application.attributeName}
</#if>
使用struts2标签输出:<@s.property value="%{Application.attributeName}"/>
2.访问HttpServletRequest中的参数
<#if Parameter.parameter?exists>
${Parameter.parameter}
</#if>
freemark的常用方法的更多相关文章
- Freemark基本语法知识(转)
FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... -->格式部分,不会输 ...
- 前端开发:Javascript中的数组,常用方法解析
前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...
- Jquery元素选取、常用方法
一:常用的选择器:(李昌辉) 基本选择器 $("#myDiv") //匹配唯一的具有此id值的元素 $("div") //匹配指定名称的所有元素 $(" ...
- python浅谈正则的常用方法
python浅谈正则的常用方法覆盖范围70%以上 上一次很多朋友写文字屏蔽说到要用正则表达,其实不是我不想用(我正则用得不是很多,看过我之前爬虫的都知道,我直接用BeautifulSoup的网页标签去 ...
- C# Webbrowser 常用方法及多线程调用
设置控件的值 /// <summary> /// 根据ID,NAME双重判断并设置值 /// </summary> /// <param name="tagNa ...
- list,tuple,dict,set常用方法
Python中list,tuple,dict,set常用方法 collections模块提供的其它有用扩展类型 from collections import Counter from collect ...
- 记录yii2-imagine几个常用方法
记录yii2-imagine几个常用方法: //压缩 Image::thumbnail('@webroot/img/test-image.jpg', 120, 120)->save(Yii::g ...
- DOM常用方法总结
DOM(Document Object Model:文档对象模型)为javascript中的一部分,它为访问和修改html文档或xml文档提供了一些编程接口,DOM以对象的形式来描述文档中的内容,以树 ...
- JSP内置对象及常用方法
jsp九大内置对象及四个作用域: 何为作用域 先让我们看看效果: 大概流程是这样的,我们访问index.jsp的时候,分别对pageContext, request, session,applicat ...
随机推荐
- linux递归查找文件内容并替换
sed -i 's/原字符串/替换后字符串/g' `grep '搜索关键字' -rl /data/目标目录/ --include "*.html"` 上面是递归查找目录中所有的HT ...
- fdisk命令详解
基础命令学习目录 原文链接:https://www.cnblogs.com/xiaofengkang/archive/2011/06/06/2073579.html fdisk -l 可以列出所有的分 ...
- Python20 - Day08
异常处理 一.什么是异常? 异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理他,则会抛出该异常,程序的运行也会停止) 错误分成两种: 1.语法错误 2.逻辑错误 二 ...
- 团队博客作业week1——成员介绍
我们小组的成员由六人组成,其中包括一名七班的韩国同学. 1.玉钟焕同学 玉钟焕是七班的同学.由于老师为了让我们尽早体验与不熟悉的同学共同工作的环境而提出团队需要跨行政班.于是我们便邀请钟焕同学加入我们 ...
- Linux 目录结构及文件基本操作
Linux 目录结构及文件基本操作 实验介绍 1.Linux 的文件组织目录结构. 2.相对路径和绝对路径. 3.对文件的移动.复制.重命名.编辑等操作. 一.Linux 目录结构 在讲 Linux ...
- 20135234mqy-——信息安全系统设计基础第三周学习总结
(1)计算机将信息按位编码,通常组成字节序列.用不同的编码方式表示整数,师叔和字符串.不同的计算机模型在编码数字和多字节数据中的字节排序时使用不同的约定. (2)C语言的设计可以包容多种不同字长和数字 ...
- imooc-c++学习感悟
imooc--慕课网c++课程链接:[课程链接](http://www.imooc.com/course/list?c=C+puls+puls) Imooc 慕课网c++学习感悟 1.课程名称:c++ ...
- 15_常用API_第15天(Object、String、StringBuffer、用户登陆注册)_讲义
今日内容介绍 1.Object 2.String 3.StringBuilder 01API概念 A:API(Application Programming Interface) 应用程序编程接口 B ...
- 由于MDK5.0A没有STM32F103程序错误 stm32f10x.h(298): error: #67: expected a "}"
转自:http://blog.163.com/lby147612@126/blog/static/17041045220150130438428/ 由于MDK4.72A没有STM32F030,所以升级 ...
- 数据库SQL中Like的用法总结
最先做项目多次用到LIKE语句,下面总结下经常用到了. 语法 match_expression [ NOT ] LIKE pattern [ ESCAPE escape_character ] 参数 ...