此片入门是对官网上的一个简单的翻译,想要快速了解freemaker并进行开发的,这一篇足已!
一、简单介绍
在程序开发中,我们可能会频繁使用到一些类似的片段,例如,展示文本的table,由于table的样式基本一样,只有数据是不一样的,那我们可以考虑把这样一个具有相同样式的table做成一个模板。使用freemaker,可以简单快捷的实现这一设计。下面来看一个简单的freemaker的模板:
<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页面一样,是存储在服务器上的,当用户访问的时候freemaker引擎能快速的把模板中的类似于${...}的内容替换成我们要展示的数据,最后展示给用户的是一个html页面,用户并不会知道我们服务器端用的是freemaker(当然我们的模板在替换之后并不会改变任何的内容,因为这个替换只发生在服务器响应的过程中)。即将要替换到模板的数据我们统称为data-model,这种数据是一个树形结构,就像我们的电脑上的文件夹和文件一样,可以被形象化这样:
(root) | +- animals | | | +- mouse | | | | | +- size = "small" | | | | | +- price = 50 | | | +- elephant | | | | | +- size = "large" | | | | | +- price = 5000 | | | +- python | | | +- size = "medium" | | | +- price = 4999 | +- message = "It is a test" | +- misc | +- foo = "Something"
这棵树通常会相对的复杂和深,可以看到这些数据就像目录一样,我们称为hashes,hashes 通常存储着其他的一些变量(如上面看到的animals,message,misc,foo等)。
对于只存储了单值的变量,如size,price等,我们称之为scalars。另外一种特殊的变量是sequences,sequence存储的子变量也像hashes一样,但是这些变量没有变量名,就像我们平时看到的数组一样。scalars储存的数据类型有:字符型、数组型、日期型、布尔型。
先来了解一点freemaker的基本语法
1、${...} 花括号内的内容将被替换成真实的值,我们称之为:interpolations 2、FTL标志 ftl的标志有点类似html,但是它们却是freemaker的指令语句,并不会被页面打印输出来,通常这些标志以#开头(用户自定义的标志使用@代替#,具有更高的优先级)、 3、注释 <#-- XXXXX -->
所有不是interpolations,ftl tag和注释的语句都会被freemaker认为是静态的文本,只做简单的输出而不会被freemaker引擎解释执行。
二、常用指令
1、The if directive
<#if animals.python.price != 0> Pythons are not free today! </#if>
<#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today. <#else> Pythons are not cheaper than elephants today. </#if>
<#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today. <#elseif animals.elephant.price < animals.python.price> Elephants are cheaper than pythons today. <#else> Elephants and pythons cost the same today. </#if>
2、The list directive
假设我们有这样的数据:
(root) | +- animals | | | +- (1st) | | | | | +- name = "mouse" | | | | | +- size = "small" | | | | | +- price = 50 | | | +- (2nd) | | | | | +- name = "elephant" | | | | | +- size = "large" | | | | | +- price = 5000 | | | +- (3rd) | | | +- name = "python" | | | +- size = "medium" | | | +- price = 4999 | +- misc | +- fruits | +- (1st) = "orange" | +- (2nd) = "banana"
freemaker遍历list的模板如下:
<p>We have these animals: <table border=1> <#list animals as animal> <tr><td>${animal.name}<td>${animal.price} Euros </#list> </table>
将输出:
<p>We have these animals: <table border=1> <tr><td>mouse<td>50 Euros <tr><td>elephant<td>5000 Euros <tr><td>python<td>4999 Euros </table>
我们需要注意这样一种情况:
<ul> <#list misc.fruits as fruit> <li>${fruit} </#list> </ul>
当misc.fruits就算是空的时候,程序仍然会输出<ul></ul>,因此我们建议这样写:
<#list misc.fruits> <ul> <#items as fruit> <li>${fruit} </#items> </ul> </#list>
另外一种情景就是我们需要用一个分隔符来并列显示我们的数组,可以写成这样:
<p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, </#list>
将输出:
<p>Fruits: orange, banana
我们用逗号来分割显示我们的数组,只有当数组后面还有其他元素时才会显示这个逗号,同样的,如果我们的数组中一个元素都没有的时候,页面上仍然会输出“Fruits:”,更好的写法应该是这样:
<p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, <#else>None</#list>
上面说到的都是一些比较简单的使用方法,我们还可以写成这样:
<p>Fruits: ${fruits?join(", ", "None")}
当然我们可以把上面说到的几种指令用在一起:
<#list misc.fruits> <p>Fruits: <ul> <#items as fruit> <li>${fruit}<#sep> and</#sep> </#items> </ul> <#else> <p>We have no fruits. </#list>
3、The include directive
使用include指令能将其他文件的内容插入到前文件中。
假设我们需要把版权信息放在每一个页面的底部,我们可以将这个版权信息做成一个模板,命名成copyright_footer.html,如下:
<hr> <i> Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>, <br> All Rights Reserved. </i>
然后每个需要添加版权信息的页面都include这个copyright_footer.html,如下:
<html> <head> <title>Test page</title> </head> <body> <h1>Test page</h1> <p>Blah blah... <#include "/copyright_footer.html"> </body> </html>
最后页面输出:一旦修改了这个copyright_footer.html文件,所有引用的页面都能立即看到这些变化。
<html> <head> <title>Test page</title> </head> <body> <h1>Test page</h1> <p>Blah blah... <hr> <i> Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>, <br> All Rights Reserved. </i> </body> </html>
4、Using built-ins(使用內建函数)
- user?upper_case 把user值变成大写 (like "JOHN DOE" instead of "John Doe")
- user?cap_first 显示首字母大写user值 (like "Mouse" instead of "mouse")
- user?length 显示user的长度值 (8 for "John Doe")
- animals?size 显示animals sequence 的元素个数
- animal.protected?string("Y", "N") 根据animal.protected这个值是true还是false,返回Y或者N
- fruits?join(", ") 把一个list用逗号分隔显示成一串字符串
- user?starts_with("J") 如果user是以J开头返回true,否则返回false
- 如果我们是在<#list animals as animal>遍历中
- animal?index 获取是从0开始的索引值
- animal?counter 获取到的是从1开始的索引值
- animal?item_parity 根据当前元素的counter值返回是字符串“odd”或者“even”,一般用在改变奇偶行的颜色,像这样
<td class="${animal?item_parity}Row">
5、处理缺省值
data-model有些变量是可选的(有些是不小心漏写了),为了识别出一些典型的人为错误,freemaker对一些缺少的变量值进行报错,除非人为的指定这个值可以为空,下面讲讲几个比较常用的方法: