`
tomgreenintel
  • 浏览: 43639 次
社区版块
存档分类
最新评论

FreeMarker小结

阅读更多
FreeMarker是一个用Java编写的模板引擎,主要用来生成HTML Web页面,特别是基于MVC模式的应用程序。虽然FreeMarker具有一些编程的能力,但不像PHP,通常由Java程序准备要显示的数据,由FreeMarker模板生成页面。 FreeMarker可以作为Web应用框架一个组件,但它与容器无关,在非Web应用程序环境也能工作的很好。 FreeMarker适合作为MVC的视图组件,还能在模板中使用JSP标记库。
<html> 
<head> 
<title>Welcome!</title> 
</head> 
<body> 
<h1>Welcome ${user}!</h1> 
<p>Our latest product: 
<a href="${latestProduct.url}">${latestProduct.name}</a>! 
</body> 
</html> 

上面的例子中,在简单的HTML中加入了一些由${…}包围的特定FreeMarker的指令,这个文件就称为模板了。而user、latestProduct.url和latestProduct.name来自于数据模型,由Java程序提供,模板设计者就不用关心数据从哪来的。
FreeMarker模板中可以包括下面四种特定部分:
一)文本:直接输出

二)FTL标记(FreeMarker模板语言标记):类似于HTML标记,名字前加#(有些以@开始,用户自定义标记)予以区分,不会输出。
1.字符串:使用单引号或双引号限定;如果包含特殊字符需要转义符:${"It's \"quoted\" andthis is a backslash: \\"}
有一类特殊的字符串:${r"C:\foo\bar"},输出结构为:C:\foo\bar,在引号前面加r被认为是纯文本。

2.数字:直接输入,不需要引号。${08}, ${+8}, ${8.00} and ${8} 都是相同的

3.布尔值:true和false,不使用引号

4.Sequences(序列)
    a.由逗号分隔的变量列表,由方括号限定,类似java中的一维数组:
          例一:["winter", "spring", "summer", "autumn"]
         例二:[2 + 2, [1, 2, 3, 4], "whatnot"] (可以嵌套)
         例三:2..5,等同于[2, 3, 4, 5];5..2,等同于[5,4,3,2]。
           注意方括号是不需要的。 (另外写法)
    b.获取Sequence(序列)中元素-使用[startindex..endindex]
         例如:seq中存储了"a", "b", "c", "d","e",
          那么seq[1..2]包含了b和c两个值。
    c.Sequences(序列)元素的遍历
           <#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
           ${user}
           </#list>
5.Hashes(散列)
     由逗号分隔的键-值列表,由大括号限定,键和值之间用冒号分隔:{"name":"green mouse", "price":150},键和值都是表达式,但是键必须是字符串。
获取变量-${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头。可以使用.variablename语法访问FreeMarker内置变量。 下列表达式是等价的:
book.author.name
book["author"].name
book.author.["name"]
book["author"]["name"]

6.字符串操作
{"Hello ${user}!"} <==> ${"Hello " + user + "!"}
${"${user}${user}${user}${user}"} <==> ${user + user + user + user}
${…}只能在文本中使用,下面是错误的代码:
<#if ${isBig}>Wow!</#if>
<#if "${isBig}">Wow!</#if> //此处的代码也是错误的,因为if指令需要的是boolean,实际的却是个字符串
子字符串的操作,
<#assign user="Big Joe">
${user[0]}${user[4]} <==> BJ
${user[1..4]} <==> ig J
注意: 操作符两边必须是数字;使用"+"时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串。

7.使用内建的指令int获得整数部分:
${(x/2)?int}
${1.1?int}
${1.999?int}
${-1.1?int}
${-1.999?int}

8.比较操作符-<#if expression>...</#if>
1.)使用=(或==,完全相等)测试两个值是否相等,使用!= 测试两个值是否不相等
2.)=和!=两边必须是相同类型的值,否则会产生错误,例如<#if 1 = "1">会引起错误
3.)Freemarker是精确比较,所以"x"、"x "和"X"是不相等的
4.)对数字和日期可以使用<、<=、>和>=,但不能用于字符串
5.)由于Freemarker会将>解释成FTL标记的结束字符,所以对于>和>=可以使用括号来避免这种情况,例如<#if (x > y)>,另一种替代的方法是,使用lt、lte、gt和gte来替代<、<=、>和>=
6.)逻辑操作符-&&(and)、||(or)、!(not),只能用于布尔值,否则会产生错误
<#if x < 12 && color = "green">
We have less than 12 things, and they are green.
</#if>
<#if !hot> <#-- here hot must be a boolean -->
It's not hot.
</#if>

9.内置函数-用法类似访问hash(散列)的子变量,只是使用"?"替代".",
例如:user?upper_case
下面列出常用的一些函数:
对于字符串
html-对字符串进行HTML编码
cap_first-使字符串第一个字母大写
lower_case-将字符串转换成小写
trim-去掉字符串前后的空白字符
对于Sequences(序列)
size-获得序列中元素的数目
对于数字
int-取得数字的整数部分(如-1.9?int的结果是-1)

10.方法的调用
${repeat("What", 3)}
${repeat(repeat("x", 2), 3) + repeat("What", 4)?upper_case}
结果:
WhatWhatWhat
xxxxxxWHATWHATWHATWHAT

11.操作符优先顺序
后缀 [subvarName] [subStringRange] . (methodParams)
一元 +expr、-expr、!
内建 ?
乘法 *、 / 、%
加法 +、-
关系 <、>、<=、>=(lt、lte、gt、gte)
相等 =、!=
逻辑 &&
逻辑 ||
数字范围 ..

12.一些常用控制语句
1)if, else, elseif
<#if x == 1>
  x is 1
  <#if y == 1>
    and y is 1 too
  <#else>
    but y is not
  </#if>
<#else>
  x is not 1
  <#if y < 0>
    and y is less than 0
  </#if>
</#if> 

2)switch, case, default, break
<#switch value>
 <#switch being.size>
  <#case "small">
     This will be processed if it is small
     <#break>
  <#case "medium">
     This will be processed if it is medium
     <#break>
  <#case "large">
     This will be processed if it is large
     <#break>
  <#default>
     This will be processed if it is neither
</#switch> 

3) list, break
<#list sequence as item>
  ${item}
  <#if item = "xx"><#break></#if>
</#list>  

4)include
<#include "/common/navbar.html" parse=false encoding="Shift_JIS">
 
5)import
<#import "/libs/mylib.ftl" as my>
<@my.copyright date="1999-2002"/>

Note: that it is possible to automatically do the commonly used imports for all templates, with the "auto imports" setting of Configuration.
6)noparse
<#noparse>
  <#list animals as being>
  <tr><td>${being.name}<td>${being.price} Euros
  </#list>
</#noparse>
 
7)compress
<#assign x = "    moo  \n\n   ">
(<#compress>
  1 2  3   4    5
  ${moo}
  test only

  I said, test only

</#compress>) 

8)escape, noescape
<#assign x = "<test>">
<#macro m1>
  m1: ${x}
</#macro>
<#escape x as x?html>
  <#macro m2>m2: ${x}</#macro>
  ${x}
  <@m1/>
</#escape>
${x}
<@m2/>  
 
 <#escape x as x?html>
  From: ${mailMessage.From}
  Subject: ${mailMessage.Subject}
  <#noescape>Message: ${mailMessage.htmlFormattedBody}</#noescape>
  ...
</#escape> 

<#escape x as x?html>
  Customer Name: ${customerName}
  Items to ship:
  <#escape x as itemCodeToNameMap[x]>
    ${itemCode1}
    ${itemCode2}
    ${itemCode3}
    ${itemCode4}
  </#escape>
</#escape>  

9)assign
<#import "/mylib.ftl" as my>
<#assign
  seasons = ["winter", "spring", "summer", "autumn"]
  test = test + 1
   bgColor="red" in my
>  
<#macro myMacro>foo</#macro>
<#assign x>
  <#list 1..3 as n>
    ${n} <@myMacro />
  </#list>
</#assign>
Number of words: ${x?word_list?size}
${x}  
<#assign x="Hello ${user}!"> 

10)global
<#global name=value>
or
<#global name1=value1 name2=value2 ... nameN=valueN>
or
<#global name>
  capture this
</#global>

11)local
note:it is similar to assign directive, but it creates or replaces local variables. This works in macro definition bodies only.
<#local name=value>
or
<#local name1=value1 name2=value2 ... nameN=valueN>
or
<#local name>
  capture this
</#local>

12)setting
note:The supported settings are:locale,number_format,boolean_format,
date_format, time_format, datetime_format,time_zone,url_escaping_charset,classic_compatible
${1.2}
<#setting locale="en_US">
${1.2} 

13) (<@...>)
<@myRepeatMacro count=4 ; x, last>
  ${x}. Something... <#if last> This was the last!</#if>
</@myRepeatMacro>  

14)macro, nested, return
<#macro img src extra...>
  <img src="/context${src?html}" 
  <#list extra?keys as attr>
    ${attr}="${extra[attr]?html}"
  </#list>
  >
</#macro>
<@img src="/images/test.png" width=100 height=50 alt="Test"/>

<#macro repeat count>
  <#list 1..count as x>
    <#nested x, x/2, x==count>
  </#list>
</#macro>
<@repeat count=4 ; c, halfc, last>
  ${c}. ${halfc}<#if last> Last!</#if>
</@repeat>  
<#macro test>
  Test text
  <#return>
  Will not be printed.
</#macro>
<@test/>  

15)function, return

<#function avg nums...>
  <#local sum = 0>
  <#list nums as num>
    <#local sum = sum + num>
  </#list>
  <#if nums?size != 0>
    <#return sum / nums?size>
  </#if>
</#function>
${avg(10, 20)}
${avg(10, 20, 30, 40)}
${avg()!"N/A"} 

16).flush
17)stop
18)ftl
19)t, lt, rt

20)nt
21)attempt, recover

Primary content
<#attempt>
  Optional content: ${thisMayFails}
<#recover>
  Ops! The optional content is not available.
</#attempt>
Primary content continued  

22)visit, recurse, fallback


三. Interpolation:由${...}或#{...}两种类型,输出计算值,可以自定义输出的格式
1)string的操作:
substring
cap_first
uncap_first
capitalize
chop_linebreak
date, time, datetime
ends_with
html
groups
index_of
j_string
js_string
last_index_of
length
lower_case
left_pad
right_pad
contains
matches
number
replace
rtf
url
split
starts_with
string (when used with a string value)
trim
upper_case
word_list
xml

2)numbers的操作:
c
string (when used with a numerical value)
round, floor, ceiling


3)dates的操作:
string (when used with a date value)
date, time, datetime

4)booleans的操作:
string (when used with a boolean value)
5)sequences的操作:
first
last
seq_contains
seq_index_of
seq_last_index_of
reverse
size
sort
sort_by
chunk

6)hashes的操作:
keys
values

7)nodes 的操作:
children
parent
root
ancestors
node_name
node_type
node_namespace


四.) 注释:<#--和-->




下面是一个常用的模板例子:
例一:
<p>We have these animals: 
<table border=1> 
<tr><th>Name<th>Price 
<#list animals as being> 
<tr> 
<td> 
<#if being.size = "large"><b></#if> 
${being.name} 
<#if being.size="large"></b></#if> 
<td>${being.price} Euros 
</#list> 
</table> 
<#include "/copyright_footer.html"> 

注意点:
1.) FreeMarker是区分大小写的;
2.) FTL标记不能位于另一个FTL标记内部,例如:<#if <#include 'foo'>='bar'>...</if>;
3.) ${…}只能在文本中使用;
4.) 多余的空白字符会在模板输出时去除;
5.) 如果使用的指令不存在,会产生一个错误消息。

例子2。
<%@ taglib uri="/WEB-INF/fmtag.tld" prefix="fm" %>
<jsp:useBean id="mybean"  class="freemarker.examples.jsp.SimpleBean"/>
<jsp:useBean id="mybeanreq" class="freemarker.examples.jsp.SimpleBean" scope="request"/>
<fm:template>
<html>
  <head>
    <title>FreeMarker JSP Example</title>
  </head>
  <body>
    <h1>FreeMarker JSP example</h1>
    <hr>
    <p>
      This page is a JSP page, yet most of its contents is generated using
      a FreeMarker template. The below lines are the output of calling
      properties on a JSP-declared bean from the FreeMarker template:
    </p>
    
    <#assign mybean = page.mybean>
    <#assign mybeanreq = request.mybeanreq>
    
    <p>page: ${mybean.string}
    <#list mybean.array as item>
      <br>${item}
    </#list>
    <br>request : ${mybeanreq.string}
    
    <p><b>Note:</b> Starting from FreeMarker 2.2 you can use custom JSP tags in
       FreeMarker templates. If you want to migrate from JSP to FTL (i.e. FreeMarker templates),
       then that's probably a better option than embedding FTL into JSP pages.
</body>
</html>
</fm:template>

fmtag.tld文件:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
        "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">

<taglib>

  <tlibversion>2.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>FreeMarker JSP Support</shortname>

  <tag>
    <name>template</name>
    <tagclass>freemarker.ext.jsp.FreemarkerTag</tagclass>
    <bodycontent>tagdependent</bodycontent>
    <info>Allows evaluation of FreeMarker templates inside JSP</info>
    <attribute>
      <name>caching</name>
      <required>false</required>
    </attribute>
  </tag>
</taglib>


例子3:
inedex.ftl 代码:

<#import "/lib/common.ftl" as com>
<#escape x as x?html>

<@com.page title="Index">
  <a href="form.do">Add new message</a> | <a href="help.html">Help</a>
  <#if guestbook?size = 0>
    <p>No messages.
  <#else>
    <p>The messages are:
    <table border=0 cellspacing=2 cellpadding=2 width="100%">
      <tr align=center valign=top>
        <th bgcolor="#C0C0C0">Name
        <th bgcolor="#C0C0C0">Message
      <#list guestbook as e>
        <tr align=left valign=top>
          <td bgcolor="#E0E0E0">${e.name} <#if e.email?length != 0> (<a href="mailto:${e.email}">${e.email}</a>)</#if>
          <td bgcolor="#E0E0E0">${e.message}
      </#list>
    </table>
  </#if>
</@com.page>
</#escape>


form.ftl代码
<#import "/lib/common.ftl" as com>
<#global html=JspTaglibs["/WEB-INF/struts-html.tld"]>
<#escape x as x?html>

<@com.page title="Add Entry">
  <@html.errors/>
  
  <@html.form action="/add">
    <p>Your name:<br>
    <@html.text property="name" size="60"/>
    <p>Your e-mail (optional):<br>
    <@html.text property="email" size="60"/>
    <p>Message:<br>
    <@html.textarea property="message" rows="3" cols="60"/>
    <p><@html.submit value="Submit"/>
  </@html.form>
  
  <p><a href="index.do">Back to the index page</a>
</@com.page>
</#escape>

add.ftl代码内容
<#import "/lib/common.ftl" as com>
<#escape x as x?html>

<@com.page title="Entry added">
  <p>You have added the following entry to the guestbook:
  <p><b>Name:</b> ${guestbookEntry.name}
  <#if guestbookEntry.email?length != 0>
    <p><b>Email:</b> ${guestbookEntry.email}
  </#if>
  <p><b>Message:</b> ${guestbookEntry.message}
  <p><a href="index.do">Back to the index page...</a>
</@com.page>
</#escape>

common.ftl的 代码
<#macro page title>
  <html>
  <head>
    <title>FreeMarker Struts Example - ${title?html}</title>
    <meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body>
    <h1>${title?html}</h1>
    <hr>
    <#nested>
    <hr>
    <table border="0" cellspacing=0 cellpadding=0 width="100%">
      <tr valign="middle">
        <td align="left">
          <i>FreeMarker Struts Example</i>
        <td align="right">
          <a href="http://freemarker.org"><img src="poweredby_ffffff.png" border=0></a>
    </table>
  </body>
  </html>
</#macro>

FreeMarker内部运行的某些原理:
个人感觉有兴趣和 时间的人可以去研究下《Programmer Guide》部分(原文档共有四个部分)该部分主要是介绍FreeMarker内部运行的某些原理


分享到:
评论
1 楼 sghcel 2011-09-15  
根本就不是讲原理的

相关推荐

    FreeMarker学习代码小结

    NULL 博文链接:https://sunfish.iteye.com/blog/1386480

    Java操作FreeMarker模板引擎的基本用法示例小结

    FreeMarker 是一个采用 Java 开发的模版引擎,是一个基于模版生成文本的通用工具。 它被设计用来生成 HTML Web 页面,特别是基于 MVC 模式的应用程序。虽然使用FreeMarker需要具有一些编程的能力,但通常由 Java ...

    深入浅出Struts2(附源码)

    1.4 小结 13 第2章初识Struts 14 2.1 Struts的优点 14 2.2 Struts的动作处理流程 15 2.3 拦截器 17 2.4 Struts配置文件 18 2.4.1 struts.xml文件 19 2.4.2 struts.properties文件 26 2.5 Struts应用程序示例...

    spring in action英文版

    第一部分 Spring基础  第1章 开始Spring之旅  1.1 为什么使用Spring  1.1.1 J2EE开发者的一天  1.1.2 Spring的承诺  1.2 Spring是什么 ... 1.7 小结 ... 2.5 小结 ... 3.7 小结 ... 11.6 小结

    深入浅出Struts 2 .pdf(原书扫描版) part 1

    1.4 小结 13 第2章 初识Struts 14 2.1 Struts的优点 14 2.2 Struts的动作处理流程 15 2.3 拦截器 17 2.4 Struts配置文件 18 2.4.1 struts.xml文件 19 2.4.2 struts.properties文件 26 2.5 Struts应用程序示例 26 ...

    Java Web程序设计教程

    程序设计教程.pdf&gt;&gt;人民邮电出版社的教程哦,所以,好书,你懂的!! 第1章web应用开发简介 1 1.1何为web应用 1 1.1.1web的概念及发展 1 1.1.2web应用程序 2 1.2使用java开发web应用 3 ...本章小结 342

    Struts2 in action中文版

    第一部分 Strut 2:一个全新的框架 第1章 Struts 2:现代Web框架 2 1.1 Web应用程序:快速学习 2 1.1.1 构建Web应用程序 2 1.1.2 基础技术简介 3 1.1.3 深入研究 6 1.2 Web应用程序框架 7 ...15.7 小结 332

    Spring in Action(第2版)中文版

    目录 第一部分spring的核心 第1章开始spring之旅 1.1spring是什么 1.2开始spring之旅 1.3理解依赖注入 ...1.5小结 ...2.6小结 ...3.7小结 ...4.6小结 ...5.8小结 ...6.5小结 ...7.7小结 ...8.6小结 ...9.6小结 ...b.4小结

    Spring in Action(第二版 中文高清版).part2

    第一部分 Spring的核心 第1章 开始Spring之旅 1.1 Spring是什么 1.2 开始Spring之旅 1.3 理解依赖注入 1.3.1 依赖注入 1.3.2 DI应用 1.3.3 企业级应用中的依赖注入 1.4 应用AOP ...B.4 小结

    Spring in Action(第二版 中文高清版).part1

    第一部分 Spring的核心 第1章 开始Spring之旅 1.1 Spring是什么 1.2 开始Spring之旅 1.3 理解依赖注入 1.3.1 依赖注入 1.3.2 DI应用 1.3.3 企业级应用中的依赖注入 1.4 应用AOP ...B.4 小结

    Struts2入门教程(全新完整版)

    一、准备工作及实例 3 ...小结Action 14 9.使用通配符 14 10.使用0配置:ZERO Annotation 15 11.Result配置详解 15 探讨type类型: 16 Type类型值 16 作用说明 16 对应类 16 chain 16 用来处理Action链 16 ...

    springboot学习

    Spring Boot Actuator监控端点小结 在传统Spring应用中使用spring-boot-actuator模块提供监控端点 Spring Boot应用的后台运行配置 Spring Boot自定义Banner Dubbo进行服务治理 chapter9-2-1:Spring Boot中使用Dubbo...

    spring boot 全面的样例代码

    - [Spring Boot Actuator监控端点小结](http://blog.didispace.com/spring-boot-actuator-1/) - [在传统Spring应用中使用spring-boot-actuator模块提供监控端点]...

    Spring-Reference_zh_CN(Spring中文参考手册)

    14.5.2. 小结 14.6. 文档视图(PDF/Excel) 14.6.1. 简介 14.6.2. 配置和安装 14.6.2.1. 文档视图定义 14.6.2.2. Controller 代码 14.6.2.3. Excel视图子类 14.6.2.4. PDF视图子类 14.7. JasperReports 14.7.1. 依赖...

Global site tag (gtag.js) - Google Analytics