`
wtnhwbb
  • 浏览: 163977 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

FreeMarker快速入门

阅读更多
xml 代码
 
  1. 1、快速入门   
  2. (1)模板 + 数据模型 = 输出   
  3.          FreeMarker基于设计者和程序员是具有不同专业技能的不同个体的观念   
  4.          他们是分工劳动的:设计者专注于表示——创建HTML文件、图片、Web页面的其它可视化方面;程序员创建系统,生成设计页面要显示的数据   
  5.          经常会遇到的问题是:在Web页面(或其它类型的文档)中显示的信息在设计页面时是无效的,是基于动态数据的   
  6.          在这里,你可以在HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker会在输出页面给最终用户时,用适当的数据替代这些代码   
  7.          下面是一个例子:   
  8. <html>  
  9. <head>  
  10.   <title>Welcome!<!---->title>  
  11. <!---->head>  
  12. <body>  
  13.   <h1>Welcome ${user}!<!---->h1>  
  14.   <p>Our latest product:  
  15.   <a href="${latestProduct.url}">${latestProduct.name}<!---->a>!  
  16. <!---->body>  
  17. <!---->html>    
  18.          这个例子是在简单的HTML中加入了一些由${…}包围的特定代码,这些特定代码是FreeMarker的指令,而包含FreeMarker的指令的文件就称为模板(Template)   
  19.          至于user、latestProduct.url和latestProduct.name来自于数据模型(data model)   
  20.          数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成   
  21.          模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型   
  22.          下面是一个可能的数据模型:   
  23. (root)  
  24.   |  
  25.   +- user = "Big Joe"  
  26.   |  
  27.   +- latestProduct  
  28.       |  
  29.       +- url = "products/greenmouse.html"  
  30.       |  
  31.       +- name = "green mouse"  
  32.           
  33.      数据模型类似于计算机的文件系统,latestProduct可以看作是目录,而user、url和name看作是文件,url和name文件位于latestProduct目录中(这只是一个比喻,实际并不存在)   
  34.          当FreeMarker将上面的数据模型合并到模板中,就创建了下面的输出:   
  35. <html>  
  36. <head>  
  37.   <title>Welcome!<!---->title>  
  38. <!---->head>  
  39. <body>  
  40.   <h1>Welcome Big Joe!<!---->h1>  
  41.   <p>Our latest product:  
  42.   <a href="products/greenmouse.html">green mouse<!---->a>!  
  43. <!---->body>  
  44. <!---->html>    
  45. (2)数据模型   
  46.          典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子:   
  47. (root)  
  48.   |  
  49.   +- animals  
  50.   |   |  
  51.   |   +- mouse  
  52.   |   |   |    
  53.   |   |   +- size = "small"  
  54.   |   |   |     
  55.   |   |   +- price = 50  
  56.   |   |  
  57.   |   +- elephant  
  58.   |   |   |     
  59.   |   |   +- size = "large"  
  60.   |   |   |     
  61.   |   |   +- price = 5000  
  62.   |   |  
  63.   |   +- python  
  64.   |       |     
  65.   |       +- size = "medium"  
  66.   |       |     
  67.   |       +- price = 4999  
  68.   |  
  69.   +- test = "It is a test"  
  70.   |  
  71.   +- whatnot  
  72.       |  
  73.       +- because = "don't know"  
  74.          类似于目录的变量称为hashes,包含保存下级变量的唯一的查询名字   
  75.          类似于文件的变量称为scalars,保存单值   
  76.          scalars保存的值有两种类型:字符串(用引号括起,可以是单引号或双引号)和数字(不要用引号将数字括起,这会作为字符串处理)   
  77.          对scalars的访问从root开始,各部分用“.”分隔,如animals.mouse.price   
  78.          另外一种变量是sequences,和hashes类似,只是不使用变量名字,而使用数字索引,如下面的例子:   
  79. (root)   
  80.   |  
  81.   +- animals  
  82.   |   |  
  83.   |   +- (1st)  
  84.   |   |   |  
  85.   |   |   +- name = "mouse"  
  86.   |   |   |  
  87.   |   |   +- size = "small"  
  88.   |   |   |  
  89.   |   |   +- price = 50  
  90.   |   |  
  91.   |   +- (2nd)  
  92.   |   |   |  
  93.   |   |   +- name = "elephant"  
  94.   |   |   |  
  95.   |   |   +- size = "large"  
  96.   |   |   |  
  97.   |   |   +- price = 5000  
  98.   |   |  
  99.   |   +- (3rd)  
  100.   |       |  
  101.   |       +- name = "python"  
  102.   |       |  
  103.   |       +- size = "medium"  
  104.   |       |  
  105.   |       +- price = 4999  
  106.   |  
  107.   +- whatnot  
  108.       |  
  109.       +- fruits  
  110.           |  
  111.           +- (1st) = "orange"  
  112.           |  
  113.           +- (2nd) = "banana"  
  114.          这种对scalars的访问使用索引,如animals[0].name   
  115. (3)模板   
  116.          在FreeMarker模板中可以包括下面三种特定部分:   
  117.          ${…}:称为interpolations,FreeMarker会在输出时用实际值进行替代   
  118.          FTL标记(FreeMarker模板语言标记):类似于HTML标记,为了与HTML标记区分,用#开始(有些以@开始,在后面叙述)   
  119.          注释:包含在<#--和-->(而不是<!---->)之间   
  120.          下面是一些使用指令的例子:   
  121.          if指令   
  122. <#if animals.python.price < animals.elephant.price>  
  123.   Pythons are cheaper than elephants today.  
  124. <#else>  
  125.   Pythons are not cheaper than elephants today.  
  126. <!---->#if>    
  127.          list指令   
  128. <p>We have these animals:  
  129. <table border=1>  
  130.   <tr><th>Name<th>Price  
  131.   <#list animals as being>  
  132.   <tr><td>${being.name}<td>${being.price} Euros  
  133.   <!---->#list>  
  134. <!---->table>    
  135. 输出为:   
  136. <p>We have these animals:  
  137. <table border=1>  
  138.   <tr><th>Name<th>Price  
  139.   <tr><td>mouse<td>50 Euros  
  140.   <tr><td>elephant<td>5000 Euros  
  141.   <tr><td>python<td>4999 Euros  
  142. <!---->table>    
  143.          include指令   
  144. <html>  
  145. <head>  
  146.   <title>Test page<!---->title>  
  147. <!---->head>  
  148. <body>  
  149.   <h1>Test page<!---->h1>  
  150.   <p>Blah blah...  
  151. <#include "/copyright_footer.html">  
  152. <!---->body>  
  153. <!---->html>    
  154.          一起使用指令   
  155. <p>We have these animals:  
  156. <table border=1>  
  157.   <tr><th>Name<th>Price  
  158.   <#list animals as being>  
  159.   <tr>  
  160.     <td>  
  161.       <#if being.size = "large"><b><!---->#if>  
  162.       ${being.name}  
  163.       <#if being.size = "large"><!---->b><!---->#if>  
  164.     <td>${being.price} Euros  
  165.   <!---->#list>  
  166. <!---->table>  
  167.    
  168.   
  169. 2、数据模型  
  170. (1)基础  
  171.          在快速入门中介绍了在模板中使用的三种基本对象类型:scalars、hashes 和sequences,其实还可以有其它更多的能力:  
  172.          scalars:存储单值  
  173.          hashes:充当其它对象的容器,每个都关联一个唯一的查询名字  
  174.          sequences:充当其它对象的容器,按次序访问  
  175.          方法:通过传递的参数进行计算,以新对象返回结果  
  176.          用户自定义FTL标记:宏和变换器  
  177.          通常每个变量只具有上述的一种能力,但一个变量可以具有多个上述能力,如下面的例子:  
  178. (root)  
  179.  |  
  180.  +- mouse = "Yerri"  
  181.      |  
  182.      +- age = 12  
  183.      |  
  184.      +- color = "brown">    
  185.          mouse既是scalars又是hashes,将上面的数据模型合并到下面的模板:  
  186. ${mouse}       <#-- use mouse as scalar -->  
  187. ${mouse.age}   <#-- use mouse as hash -->  
  188. ${mouse.color} <#-- use mouse as hash -->    
  189.          输出结果是:  
  190. Yerri  
  191. 12  
  192. brown    
  193. (2)Scalar变量  
  194.          Scalar变量存储单值,可以是:  
  195.          字符串:简单文本,在模板中使用引号(单引号或双引号)括起  
  196.          数字:在模板中直接使用数字值  
  197.          日期:存储日期/时间相关的数据,可以是日期、时间或日期-时间(Timestamp);通常情况,日期值由程序员加到数据模型中,设计者只需要显示它们  
  198.          布尔值:true或false,通常在<#if …>标记中使用  
  199. (3)hashes 、sequences和集合  
  200.          有些变量不包含任何可显示的内容,而是作为容器包含其它变量,者有两种类型:  
  201.          hashes:具有一个唯一的查询名字和它包含的每个变量相关联  
  202.          sequences:使用数字和它包含的每个变量相关联,索引值从0开始  
  203.          集合变量通常类似sequences,除非无法访问它的大小和不能使用索引来获得它的子变量;集合可以看作只能由<#list …>指令使用的受限sequences  
  204. (4)方法  
  205.          方法变量通常是基于给出的参数计算值  
  206.          下面的例子假设程序员已经将方法变量avg放到数据模型中,用来计算数字平均值:  
  207. The average of 3 and 5 is: ${avg(3, 5)}  
  208. The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}  
  209. The average of the price of python and elephant is: ${avg(animals.python.price, animals.elephant.price)}  
  210. (5)宏和变换器  
  211.          宏和变换器变量是用户自定义指令(自定义FTL标记),会在后面讲述这些高级特性  
  212. (6)节点  
  213.          节点变量表示为树型结构中的一个节点,通常在XML处理中使用,会在后面的专门章节中讲述  
  214.    
  215. 3、模板  
  216. (1)整体结构  
  217.          模板使用FTL(FreeMarker模板语言)编写,是下面各部分的一个组合:  
  218.          文本:直接输出  
  219.          Interpolation:由${和},或#{和}来限定,计算值替代输出  
  220.          FTL标记:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出  
  221.          注释:由<#--和-->限定,不会输出  
  222.          下面是以一个具体模板例子:  
  223. <html>[BR]  
  224. <head>[BR]  
  225.   <title>Welcome!<!---->title>[BR]  
  226. <!---->head>[BR]  
  227. <body>[BR]  
  228.   <#-- Greet the user with his/her name -->[BR]  
  229.   <h1>Welcome ${user}!<!---->h1>[BR]  
  230.   <p>We have these animals:[BR]  
  231.   <ul>[BR]  
  232.   <#list animals as being>[BR]  
  233.     <li>${being.name} for ${being.price} Euros[BR]  
  234.   <!---->#list>[BR]  
  235.   <!---->ul>[BR]  
  236. <!---->body>[BR]  
  237. <!---->html>    
  238.          [BR]是用于换行的特殊字符序列  
  239.          注意事项:  
  240.          FTL区分大小写,所以list是正确的FTL指令,而List不是;${name}和${NAME}是不同的  
  241.          Interpolation只能在文本中使用  
  242.          FTL标记不能位于另一个FTL标记内部,例如:  
  243. <#if <#include 'foo'>='bar'>...<!---->if>  
  244.          注释可以位于FTL标记和Interpolation内部,如下面的例子:  
  245. <h1>Welcome ${user <#-- The name of user -->}!<!---->h1>[BR]  
  246. <p>We have these animals:[BR]  
  247. <ul>[BR]  
  248. <#list <#-- some comment... --> animals as <#-- again... --> being>[BR]  
  249. ...    
  250.          多余的空白字符会在模板输出时移除  
  251. (2)指令  
  252.          在FreeMarker中,使用FTL标记引用指令  
  253.          有三种FTL标记,这和HTML标记是类似的:  
  254.          开始标记:<#directivename parameters>  
  255.          结束标记:<!---->#directivename>  
  256.          空内容指令标记:<#directivename parameters/>  
  257.          有两种类型的指令:预定义指令和用户定义指令  
  258.          用户定义指令要使用@替换#,如<@mydirective>...<!---->@mydirective>(会在后面讲述)  
  259.          FTL标记不能够交叉,而应该正确的嵌套,如下面的代码是错误的:  
  260. <ul>  
  261. <#list animals as being>  
  262.   <li>${being.name} for ${being.price} Euros  
  263.   <#if use = "Big Joe">  
  264.      (except for you)  
  265. <!---->#list>  
  266. <!---->#if><#-- WRONG! -->  
  267. <!---->ul>    
  268.          如果使用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息  
  269.          FreeMarker会忽略FTL标记中的空白字符,如下面的例子:  
  270. <#list[BR]  
  271.   animals       as[BR]  
  272.      being[BR]  
  273. >[BR]  
  274. ${being.name} for ${being.price} Euros[BR]  
  275. <!---->#list    >    
  276.          但是,<<!---->和指令之间不允许有空白字符  
  277. (3)表达式  
  278.          直接指定值  
  279.          字符串  
  280.          使用单引号或双引号限定  
  281.          如果包含特殊字符需要转义,如下面的例子:  
  282. ${"It's \"quoted\" and  
  283. this is a backslash: \\"}  
  284.    
  285. ${'It\'s "quoted" and  
  286. this is a backslash: \\'}   
  287. 输出结果是:  
  288. It's "quoted" and  
  289. this is a backslash: \  
  290.    
  291. It's "quoted" and  
  292. this is a backslash: \   
  293.          下面是支持的转义序列:  
  294. 转义序列    含义  
  295. \"  双引号(u0022)  
  296. \'  单引号(u0027)  
  297. \\  反斜杠(u005C)  
  298. \n  换行(u000A)  
  299. \r  Return (u000D)  
  300. \t  Tab (u0009)  
  301. \b  Backspace (u0008)  
  302. \f  Form feed (u000C)  
  303. \l  <  
  304. \g  >  
  305. \a  &  
  306. \{  {  
  307. \xCode  4位16进制Unicode代码  
  308.          有一类特殊的字符串称为raw字符串,被认为是纯文本,其中的\和{等不具有特殊含义,该类字符串在引号前面加r,下面是一个例子:  
  309. ${r"${foo}"}  
  310. ${r"C:\foo\bar"}    
  311. 输出的结果是:  
  312. ${foo}  
  313. C:\foo\bar    
  314.          数字  
  315.          直接输入,不需要引号  
  316.          精度数字使用“.”分隔,不能使用分组符号  
  317.          目前版本不支持科学计数法,所以“1E3”是错误的  
  318.          不能省略小数点前面的0,所以“.5”是错误的  
  319.          数字8、+8、08和8.00都是相同的  
  320.          布尔值  
  321.          true和false,不使用引号  
  322.          序列  
  323.          由逗号分隔的子变量列表,由方括号限定,下面是一个例子:  
  324. <#list ["winter", "spring", "summer", "autumn"] as x>  
  325. ${x}  
  326. <!---->#list>   
  327. 输出的结果是:  
  328. winter  
  329. spring  
  330. summer  
  331. autumn  
  332.          列表的项目是表达式,所以可以有下面的例子:  
  333. [2 + 2, [1, 2, 3, 4], "whatnot"]  
  334.          可以使用数字范围定义数字序列,例如2..5等同于[2, 3, 4, 5],但是更有效率,注意数字范围没有方括号  
  335.          可以定义反递增的数字范围,如5..2  
  336.          散列(hash)  
  337.          由逗号分隔的键/值列表,由大括号限定,键和值之间用冒号分隔,下面是一个例子:  
  338. {"name":"green mouse", "price":150}  
  339.          键和值都是表达式,但是键必须是字符串  
  340.          获取变量  
  341.          顶层变量: ${variable},变量名只能是字母、数字、下划线、$、@和#的组合,且不能以数字开头  
  342.          从散列中获取数据  
  343.          可以使用点语法或方括号语法,假设有下面的数据模型:  
  344. (root)  
  345.  |  
  346.  +- book  
  347.  |   |  
  348.  |   +- title = "Breeding green mouses"  
  349.  |   |  
  350.  |   +- author  
  351.  |       |  
  352.  |       +- name = "Julia Smith"  
  353.  |       |  
  354.  |       +- info = "Biologist, 1923-1985, Canada"  
  355.  |  
  356.  +- test = "title"   
  357. 下面都是等价的:  
  358. book.author.name  
  359. book["author"].name  
  360. book.author.["name"]  
  361. book["author"]["name"]  
  362.          使用点语法,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字是任意表达式的结果  
  363.          从序列获得数据:和散列的方括号语法语法一样,只是方括号中的表达式值必须是数字;注意:第一个项目的索引是0  
  364.          序列片断:使用[startIndex..endIndex]语法,从序列中获得序列片断(也是序列);startIndex和endIndex是结果为数字的表达式  
  365.          特殊变量:FreeMarker内定义变量,使用.variablename语法访问  
  366.          字符串操作  
  367.          Interpolation(或连接操作)  
  368.          可以使用${..}(或#{..})在文本部分插入表达式的值,例如:  
  369. ${"Hello ${user}!"}  
  370. ${"${user}${user}${user}${user}"}    
  371.          可以使用+操作符获得同样的结果  
  372. ${"Hello " + user + "!"}  
  373. ${user + user + user + user}  
  374.          ${..}只能用于文本部分,下面的代码是错误的:  
  375. <#if ${isBig}>Wow!<!---->#if>  
  376. <#if "${isBig}">Wow!<!---->#if>  
  377. 应该写成:  
  378. <#if isBig>Wow!<!---->#if>  
  379.          子串  
  380.          例子(假设user的值为“Big Joe”):  
  381. ${user[0]}${user[4]}  
  382. ${user[1..4]}  
  383. 结果是(注意第一个字符的索引是0):  
  384. BJ  
  385. ig J   
  386.          序列操作  
  387.          连接操作:和字符串一样,使用+,下面是一个例子:  
  388. <#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>  
  389. - ${user}  
  390. <!---->#list>  
  391. 输出结果是:  
  392. - Joe  
  393. - Fred  
  394. - Julia  
  395. - Kate  
  396.          散列操作  
  397.          连接操作:和字符串一样,使用+,如果具有相同的key,右边的值替代左边的值,例如:  
  398. <#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>  
  399. - Joe is ${ages.Joe}  
  400. - Fred is ${ages.Fred}  
  401. - Julia is ${ages.Julia}    
  402. 输出结果是:  
  403. - Joe is 30  
  404. - Fred is 25  
  405. - Julia is 18    
  406.          算术运算  
  407.          +、-、×、/、%,下面是一个例子:  
  408. ${x * x - 100}  
  409. ${x / 2}  
  410. ${12 % 10}  
  411. 输出结果是(假设x为5):  
  412. -75  
  413. 2.5  
  414. 2    
  415.          操作符两边必须是数字,因此下面的代码是错误的:  
  416. ${3 * "5"} 
分享到:
评论
1 楼 alanlhy 2012-03-09  
整理的不错,不过就是字有些太小了,而且有些地方貌似出现了错误。。。

相关推荐

Global site tag (gtag.js) - Google Analytics