浏览 7948 次
锁定老帖子 主题:FreeMarker学习笔记
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-09-12
2. 数据模型 a) 类似目录的变量称为hashes,包含保存下级变量的唯一的查询名字,充当其它对象的容器,每个都关联唯一的查询名字 b) 类似文件的变量称为scalars,保存单值,有两种类型 i. 字符串:用引号括起,单引号or双引号 ii. 数字:不用引号 iii. 日期:可以是日期,时间或日期-时间 iv. 布尔值:true或false,通常在<#if …>标记中使用 v. 对scalars的访问从root开始,各部分用”.”分隔,如 animals.mouse.price c) 另外一种变量是sequences,和hashes类似,充当其它对象的容器,按次序访问,只是不使用变量名字,而使用数字索引,如animals[0].name,索引值从0开始 d) 通常每个变量具有上述的一种能力,但一个变量可以具有多种上述能力 e) 方法 i. ${avg(3,5,20)} ${avg(student.zhangyaang.age,student.situ.age)} f) 宏和变换器:用户自定义的指令(FTL标记) g) 节点:树形结构中的一个节点,常用于xml处理中 3. 模板 a) 文本:直接输出 b) ${…}:称为interpolations,FreeMarker会在输出时用实际值代替,或#{},只用于文本中 c) FTL标记:类似于HTML,为了与HTML区分,用#开始,有的以@开始,不会输出,区分大小写,FTL标记不能位于另一个FTL标记内部 d) 注释:<#--和-->,不会输出 e) 多余的空白字符会在模板输出时移除 f) 指令 i. 使用FTL标记引用指令,有三种FTL标记 1. 开始标记:<#name prarm> 2. 结束标记:</#name> 3. 空内容指令标记:<#name param /> ii. 有两种类型的指令:预定义指令和用户定义指令,用户定义指令要用@替换# iii. FTL标记不能够交叉,应该正确嵌套 iv. 如果使用不存在的指令,FreeMarker会产生错误消息 v. < , </ 和指令间不允许有空白字符 g) 表达式 i. 字符串 1. 使用单引号或双引号限定 2. 特殊字符要转义 3. raw字符串,可以认为是文本,其中的$和{等不具有特殊含义,该类字符串在引号前面加r,如${r”${foo}”} ${r”c:\foo\bar”} ii. 数字 1. 直接输入,不需要引号 2. 精度数字使用”.”分隔,不能使用分组符号 3. 不支持科学计数法 4. 不能省略小数点前面的0 5. 数字8 ,+8 ,08和8.00 都是相同的 iii. 布尔值:true 和 false, 不使用引号 iv. 序列 1. 有逗号分隔的子变量列表,有方括号限定,如: <#list [“winter”, ”spring”, ”summer”, ”autumn”] as x> ${x} </#list> 2. 列表的项目是表达式,如: [2+2, [1,2,3,4], ”whatnot”] 3. 可以使用数字范围定义数字序列,如: 2..5等同于[2,3,4,5] 注意:数字范围没有方括号 如:5..2 4. 散列(hash) 由逗号的键/值列表,有大括号限定,键和值之间用冒号分隔 {“name”:”zhangyang”,”age”:23} 键和值都是表达式,但键必须是字符串 v. 获取变量 1. 顶层变量:${variable}, 变量名只能是字母, 数字, 下划线, $, @ 和# 的组合, 不能以数字开头 2. 从散列中获取数据 a) school.student.name b) school.[“student”].name c) school[“student”][“name”] 说明:使用点语法,变量名有顶层变量一样的限制, 方括号语法没有该限制 3. 从序列获(sequences)得数据: 和散列的方括号语法一样, 只是方括号的表达式值必须是数字; 注意: 第一个项目的索引是0 4. 序列片段: 使用[startIndex..endIndex]语法, 从序列中获得片段(也是序列) 5. 特殊变量: FreeMarker内定义的变量, 使用 .variablenae 语法访问 vi. 字符串操作 1. Interpolation(或连接操作) a) 可以使用${..} 或#{..} 在文本部分插入表达式的值, 如${“Hello ${user}”} 等于 ${“Hello”+user} b) ${..} 只能用于文本部分, 不用于FTL表达式中 2. 子串 假设user的值为”tom cat” ${user[0]}${user[4]} tc ${user[1..4]} om c vii. 序列操作 连接操作: 和字符串一样, 用”+” <#list [“joe”,”fred”] + [“julia”,”kate”] as user> ${user} </#list> viii. 散列操作 连接操作: 和字符串一样, 用”+”, 如果有相同的key, 右边的值替换左边的值(后面的替换前面的), 如 <#assign ages = {“joe”:23,”fred”:25} + {“joe”:30,”julia”:23}> </#assign> 结果: joe的值为30 ix. 算术运算 1. +, -- , *, /, % ${x / 2} 2. 操作符两边必须是数字 3. 使用 “+” 操作符时,如果一边是数字, 一边是字符串, 就会自动将数字转换为字符串, 如: ${3+”4”} 结果 34 4. 使用内建的 int 获得整数部分 ${1.1?int} 1 ${1.999?int} 1 ${(5/2)?int} 2 5. 比较操作符 a) 使用=(或==,完全相等)测试两个值是否相等, 使用!=测试两个值是否不相等 b) = 和!= 两边必须是相同类型的值 c) FreeMarker是精确比较,”x”,”x “和”x”是不等的 d) 对数字和日期可以使用<, <=, >, 和>=, 但不用用于字符串 e) 由于FreeMarker 会将>解释成FTL标记的结束字符, 所以对于>和>=可以使用括号来避免这种情况, 如<#if (x > y)> f) e)的一种替代方法, 使用lt, lte, gt 和gte来替代 6. 逻辑操作符 a) &&(and), ||(or), !(not), 只能用于布尔值 <#if x < 13 && color = “green”> … </#if> <#if ! man> woman </#if> 7. 内建函数 a) 内建函数的用法类似访问散列的子变量, 只是用”?”|替代”,” b) 用于字符串 i. html: 对字符串进行html编码 ii. cap_first: 将字符串转换成第一个字母大写 iii. lower_case: 小写 iv. upper_case: 大写 v. trim: 去掉字符串前后的空白字符 c) 用于序列 i. size: 获得序列中元素的数目 d) 用于数字 i. int: 取得数字的整数部分 e) 例子: test = “tom & jerry” ${test?html} tom & jerry ${test?upper_case?html} TOM & JERRY 8. 操作符优先顺序 h) Interpolation(只用于文本部分) i. Interpolation有两种类型 1. 通用Interpolation: ${expr} a) 插入字符串值: 直接输出表达式结果 b) 插入数字值: 根据缺省格式(由#setting指令设置)将表达式转换成文本输出; 可以使用内建函数string格式化单个Interpolation c) 例子 <#setting number_format=”currency”/> 金额 <#assign answer=43/> ${answer} $43.00 ${answer?string} $43.00 ${answer?string.number} 43 ${answer?string.currency} $43.00 ${answer?string.percent} 4,300% 2. 数字Interpolation: ${expr} 或#{expr ; format} 3. 插入日期: 根据缺省格式(#setting) 将表达式结果转换成文本输出; 可以使用内建的函数string 格式化单个Interpolation, 例子: ${update?string(“yyyy-MM-dd HH:mm:ss zzzz”)} 4. 插入布尔值: 说明同上 <#assign foo = true/> ${foo?string(“yes”,”no”)} yes 5. 数字Interpolation的#{expr ; format}形式可以用来格式化数字, format可以是 a) mX: 小数部分最小X位 b) MX: 小数部分最大X位 c) 例子 <#assign x=2.364/> <#assign y=4/> #{x; M2} 2.36 #{y; M2} 4 #{x; m1} 2.4 #{y; m1} 4.0 i) 例子 i. if指令 <#if zhangyang.age < situ.age> Situ is order <#else> Zhangyang is order </#if> ii. list指令 <#list students[0..5] as s_list></#list>取list的前5条记录 <table border = “1”> <tr> <td>name</td><td>age</td> <#list students as s_list> <td>${s_list.name}</td><td>${s_list.age}</td> </#list> </tr> </table> iii. include指令 <#include “/all/header.html”> … <#include “/all/footer.html”> iv. 应用 <table> <#list students as s_list> <tr> <td> <#if s_list.sex =”man”><img src=”/img/boy.gif”/> <#else><img src=”/img/girl.gif/> </#if> ${s_list.name} </td> <td>${s_list.age}</td> </tr> </#list> </table> 4. 用户自定义指令 a) 宏和变换器 b) 模板中定义变量 c) 名字空间(命名空间) 5. 应用 a) List i. 例子1 List scalarList = new ArrayList(); scalarList.add("red"); scalarList.add("green"); scalarList.add("blue"); scalarList.add("yellow"); root.put("scList", scalarList); <#list scList as the_value> Scalar List值:${the_value} </#list> ii. 例子2 public class User { private String userId; private String userName; } User u1 = new User(); u1.setUserId("100"); u1.setUserName("郜司徒"); User u2 = new User(); u2.setUserId("200"); u2.setUserName("张宇伟"); User u3 = new User(); u3.setUserId("300"); u3.setUserName("冯钰凯"); User u4 = new User(); u4.setUserId("400"); u4.setUserName("苗先杰"); SimpleSequence userList = new SimpleSequence(ObjectWrapper.BEANS_WRAPPER); userList.add(u1); userList.add(u2); userList.add(u3); userList.add(u4); root.put("userList", userList); <#list userList as list> List对象user的值:${list.userId} List的value:${list.userName} </#list> b) Map i. 例子1 SimpleHash scalarMap = new SimpleHash(ObjectWrapper.BEANS_WRAPPER); scalarMap.put("anotherString", "aaaaaaaa"); scalarMap.put("anotherNumber", new Double(2.5555)); root.put("scMap", scalarMap); <#list scMap?keys as myKey> Map key is:${myKey} map value is:${scMap[myKey]} </#list> ii. 例子2 SimpleHash userMap = new SimpleHash(ObjectWrapper.BEANS_WRAPPER); userMap.put("1", u1); userMap.put("2", u2); userMap.put("3", u3); userMap.put("4", u4); root.put("user", userMap); <#list user?keys as key1> ${key1} ${user[key1].userId} ${user[key1].userName} <#assign u = "${user[key1]}"> User is :${u} </#list> c) List和Map SimpleHash root = new SimpleHash(/*ObjectWrapper.BEANS_WRAPPER*/); // Map<String,String> my_map = new HashMap<String,String>(); SimpleHash my_map = new SimpleHash(); my_map.put("1", "ehow"); my_map.put("2", "laomiao"); my_map.put("3", "yukai"); my_map.put("zt", "北京中天诺士达"); SimpleHash my_map2 = new SimpleHash(); my_map2.put("1", "ehow2"); my_map2.put("2", "laomiao2"); my_map2.put("3", "yukai2"); my_map2.put("zt", "北京中天诺士达2"); SimpleHash my_map3 = new SimpleHash(); my_map3.put("1", "ehow3"); my_map3.put("2", "laomiao3"); my_map3.put("3", "yukai3"); my_map3.put("zt", "北京中天诺士达3"); SimpleHash my_map4 = new SimpleHash(); my_map4.put("1", "ehow4"); my_map4.put("2", "laomiao4"); my_map4.put("3", "yukai4"); my_map4.put("zt", "北京中天诺士达4"); // List<Map> userList = new ArrayList<Map>(); SimpleSequence userList=new SimpleSequence(/*ObjectWrapper.BEANS_WRAPPER*/); userList.add(my_map); userList.add(my_map2); userList.add(my_map3); SimpleSequence userList2 = new SimpleSequence(); userList2.add(my_map4); userList2.add(my_map4); userList2.add(my_map4); root.put("the_list", userList); root.put("other_list", userList2); <div id="Layer1"> <table border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#FF0000"> <tr> <td width="100" height="30" align="center" bgcolor="#FFFFFF">代号</td> <td width="100" align="center" bgcolor="#FFFFFF">代号2</td> <td width="100" align="center" bgcolor="#FFFFFF">代号3</td> <td width="405" height="30" align="center" bgcolor="#FFFFFF">明细</td> </tr> <#list the_list as list> <tr> <td width="100" height="30" align="center" bgcolor="#FFFFFF">${list["1"]}</td> <td width="100" align="center" bgcolor="#FFFFFF">${list["2"]}</td> <td width="100" align="center" bgcolor="#FFFFFF">${list["3"]}</td> <td height="30" align="center" bgcolor="#FFFFFF">${list.zt}</td> </tr> </#list> <#list other_list as list2> <tr> <td width="100" height="30" align="center" bgcolor="#FFFFFF">${list2["1"]}</td> <td width="100" align="center" bgcolor="#FFFFFF">${list2["2"]}</td> <td width="100" align="center" bgcolor="#FFFFFF">${list2["3"]}</td> <td height="30" align="center" bgcolor="#FFFFFF">${list2["zt"]}</td> </tr> </#list> </table> </div> d) 与Hibernate结合 DAO String hql = "select new map(s.s_name as s_n,s.s_addr as s_a,h.h_addr as h_a,u.u_name as u_n) from User_school as s,User_home as h,User_info as u where u.id=h.id and h.id=s.id"; // String hql = "select new map(s.s_name as s_n,s.s_addr as s_a) from User_school as s"; List my = session.createQuery(hql).list(); Hello hello = new Hello(); hello.sayHello(my); 通用方法 public void sayHello(List info){ ... root.put("from_db", info); ... } FTL <#list from_db as db> ${db.s_n} ${db.s_a} ${db.h_a} ${db.u_n} </#list> e) 我们的项目 <#assign n = list5?size /> //定义n的值为list5的大小 <#if n gt 6> //如果n大于6,页面中可能要求只显示6条 <#assign n = 6 /> //把n重定义为6 </#if> <#if n!=0> //防止n的值为0,也可以写成<#if n gt 0 > <#list 0..(n-1) as i> //把前 n 条 记录赋值给 i,如果i=3,则[0,1,2] <#assign ls5 = list5[i] /> //把list5的第i个元素赋值给ls5 <#assign isNew = list5Istrue[i] /> <tr> <td height='25' class='z3'>.<a href='#' onclick="zw('${ls5.CIid}','905','活动展示','');"> <#if ls5.CTitle?length lt 15> //如果Ctitle的长度小于15,就 ${ls5.CTitle} //就正常显示该标题 <#else> //如果大于15 ${ls5.CTitle[0..15]}... //就截取前15个,并加上… </#if> <#if isNew="true"> <img src='/model/img/new-111.gif' width='27' height='11' border='0' /> </#if> </a></td> </tr> </#list> </#if> 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-09-12
其实也不是什么原创的东西,是自己从网上整理的资料,后面加了几个自己写的小例子,希望对刚开始学的同志有一点点的帮助
|
|
返回顶楼 | |
发表时间:2008-09-12
最好把代码整理一下,这样看着太累
|
|
返回顶楼 | |
发表时间:2008-09-19
已经把pdf上传了
|
|
返回顶楼 | |