freemaker中文文档(1)

FreeMaker Quick Start

(本人翻译,希望与大家一起分享,如果有错误,请不吝赐教!谢谢)

第一章 开始

本章内容

Template + data-model = output

数据模型概述

模板概述

本章内容是粗略的介绍了FreeMarker。本章介绍的内容都不涉及技术细节,但是读过本章后,你可以做出简单又实用的FreeMaker模板了。

Template + data-model = output

假设你的网上购物项目需要如下一个HTML页面:

<html>

<head>

  <title>Welcome!</title>

</head>

<body>

  <h1>Welcome Big Joe!</h1>

  <p>Our latest product:

  <a href="products/greenmouse.html">green mouse</a>!

</body>

</html> 

在这个页面中,欢迎信息中的用户名(这里是“Big Joe”)应显示登录的用户姓名,而且最新的产品“green mouse”应该动态的从数据库中获取,这就意味着它的信息可能随时改变。在这种情况下,你就不能够实用静态页面,把这些信息直接编码在HTML中。

对于以上的情况,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> 

这个模板保存在服务器端,与通常的静态页面相同。但是当有请求访问时,FreeMaker会把模板内的 ${...}更新为对应的对象属性或数值(例如,将${user}翻译成访问者的信息),翻译成普通的静态页面,将结果显示在用户的浏览器中。因此,此时用户的浏览器上收到的信息会是类似于我们第一个HTML的页面,而且用户不会感到我们在服务器端使用了FreeMaker。但是模板本身在这次使用过程中不会发生变化,因此这个模式可以重用,为每个访问者创建他们自己的页面。而且信息总是最新的。

现在,我们来看看数据是如何从内存中写到页面上的。FreeMaker的思想是遵从页面与业务逻辑分离的,因此在模板中我们只解决如何显示的问题,而数据的组织是在FreeMaker之外,通常是JAVA或其他语言编写的程序来负责的。因此模板的编写者不用关心数据将如何得到,所以FreeMaker的模板有更强的重用性。

FreeMaker和制作模板的人员虽然不关心数据的来源,但是他们仍然知道模板中要使用的数据是什么。所有的模板可用数据被包装在数据模型(data-model中。数据模型的存储方式是一个树形,如下:

(root)

  |

  +- user = "Big Joe"

  |

  +- latestProduct

      |

      +- url = "products/greenmouse.html"

      |

      +- name = "green mouse" 

最后,我们总结一下:FreeMaker通过模板(template)和数据模型(data-model)构建静态页面:Template + data-model = output

数据模型概述

像我们看到的,数据模型以树形方式存储数据,它可以任意扩展深度和广度:

(root)

  |

  +- animals

  |   |

  |   +- mouse

  |   |   |  

  |   |   +- size = "small"

  |   |   |  

  |   |   +- price = 50

  |   |

  |   +- elephant

  |   |   |  

  |   |   +- size = "large"

  |   |   |  

  |   |   +- price = 5000

  |   |

  |   +- python

  |       |  

  |       +- size = "medium"

  |       |  

  |       +- price = 4999

  |

  +- test = "It is a test"

  |

  +- whatnot

      |

      +- because = "don't know" 

那些类似根节点的变量( root, animals, mouse, elephant, python, whatnot)我们称为哈希表(hashes很像java中的map哈希表利用唯一关键字(, "animals", "mouse" or "price")存储变量

那些存储单个变量值的单位(如size, price, test and because)称为标量。

当你想在模板里使用已有的变量时,只要写出它们的“路径”,用“.”把路径连接起来。例如,我们要访问例子中的mouseprice时,“路径”为animals.mouse.price,再写入符号${…..}内,这时FreeMaker就可以根据我们提供的信息取出对应的数据了。

除了哈希表外,FreeMaker有另外一种存储方式:序列(sequences)。序列与哈希表很相似(本人觉得更像数组),不同的是它存储变量的方式不是利用关键字,而是顺序的将变量存储起来。例如,在下面的数据模型中,animals whatnot.fruits属于序列:

(root)

  |

  +- animals

  |   |

  |   +- (1st)

  |   |   |

  |   |   +- name = "mouse"

  |   |   |

  |   |   +- size = "small"

  |   |   |

  |   |   +- price = 50

  |   |

  |   +- (2nd)

  |   |   |

  |   |   +- name = "elephant"

  |   |   |

  |   |   +- size = "large"

  |   |   |

  |   |   +- price = 5000

  |   |

  |   +- (3rd)

  |       |

  |       +- name = "python"

  |       |

  |       +- size = "medium"

  |       |

  |       +- price = 4999

  |

  +- whatnot

      |

      +- fruits

          |

          +- (1st) = "orange"

          |

          +- (2nd) = "banana" 

访问序列中变量的方式是将它们(变量)的位置用数字标识,并且用“[ ]”括起来,写在它们的“路径”后。变量起始位置的数字标识为“0”(或者说从0开始),所以与JAVA中的数组相同,例如我们要得到上面例子中第一个animals中的变量的名称时,应该这样标示:animals[0].name。而要得到whatnot.fruits中第二个变量的名称时应该这样表示:whatnot.fruits[1].

标量可以更细的分为下列类型:

·         String:字符串类型。

·         Number:数字类型。

·         Date/time:日期类型。

·         Boolean:布尔类型。

总结:

·         数据模型可以被表述为树形。

·         标量是指存储基本类型变量(字符串类型、数字类型、日期类型或布尔类型)的数据模型。

·         哈希表利用唯一关键字存储标量。

·         序列顺序存储标量,变量的值可以通过它在序列中的位置得到。

模板概述

最简单的模板是空白的HTML文件(或者是任何空白文档文件—FreeMaker并没有限制一定是HTML)。当客户端访问这个页面时,FreeMaker将发送HTML到客户端。如果你希望你的网页可以动态的展示信息,那么我们要了解模板中的运算符(或者是标签)如何使用。

·         ${……}FreeMaker基本运算符。FreeMarker在翻译时会将运算符用变量的数值替换,这个过程我们成为转译(interpolations)。

·         FTL 标签(FreeMarker语言的标签)::标签。FTL 标签有点像HTML标签,但是它们作为FreeMaker的运算符,在生成的HTML中不会看到。它们以“#”开头(用户定义的标签用“@开头而不是“#”,我们现在先不讨论用户自定义标签)

·         注释:HTML注释类似,但是FreeMaker的注释是以 <#--开头,以-->结束的。所有注释中的内容都会被FreeMaker忽略,也不会被转译并发送到客户端。

在页面中,除了上述所说的内容我们都认为是静态的信息,都不会被FreeMaker转译而直接发送到客户端。

FTL标签也被称为标识(directives)。它和HTML标签的语法相同(如<table> and </table>),都要求标签闭合。

标识的例子

尽管FreeMaker有很多的标识,但是在这里我们只关注其中的最常用的三个标识。

if 标识

使用if标识,我们可以根据条件的显示模板中的内容。下面我们稍微修改一下第一个例子,只有我们的老板Big Joe访问时出现问候语“我们深受爱戴的领导啊~!”(老外也会拍马屁):

<html>
           
           
<head>
           
           
  <title>Welcome!</title>
           
           
</head>
           
           
<body>
           
           
  <h1>
           
           
    Welcome ${user}<#if user == "Big Joe">, our beloved leader</#if>!
           
           
  </h1>
           
           
  <p>Our latest product:
           
           
  <a href="${latestProduct.url}">${latestProduct.name}</a>!
           
           
</body>
           
           
</html>  
          
          

上面的if标识告诉FreeMaker,“our beloved leader”这句马屁在用户名为“Big Joe”时出现,而如果user == "Big Joe"条件不满足时,则不显示在<#if condition> </#if>中间的内容。

我们在上面的例子中看到,“==”是用来验证其左面的变量值是否与右面的值相等,之后为标识返回一个布尔值。“==”的左边是一个已知变量,右面放置的是一个字符串,在FreeMaker中,所有的字符串必须用引号括起来。

下面的例子:只有animals.python.price0时,"Pythons are free today!"才会被输出。

<#if animals.python.price == 0>
           
           
  Pythons are free today!
           
           
</#if>  
          
          

与上面的例子类似,这次判断的变量类型为数字类型,需要注意的是,如果我们把等号右边写成“0”,则FreeMaker将做出错误的判断,认为animals.python.price为字符串类型。

如果变量的price值不为 0时,"Pythons are not free today!"会被打印:

<#if animals.python.price != 0>
           
           
  Pythons are not free today!
           
           
</#if>  
          
          

显而易见,“!=”标识不等于。

我们也可以这样组织判断条件:

<#if animals.python.price < animals.elephant.price>
           
           
  Pythons are cheaper than elephants today.
           
           
</#if>  
          
          

if标识中还可以加入 <#else> 标签,让我们可以做更多的事情,如:

<#if animals.python.price < animals.elephant.price>
           
           
  Pythons are cheaper than elephants today.
           
           
<#else>
           
           
  Pythons are not cheaper than elephants today.
           
           
</#if>  
          
          

条件animals.python.price < animals.elephant.price满足时输出This prints ''Pythons are cheaper than elephants today.''反之则输出 ''Pythons are not cheaper than elephants today.''

如果我们有个布尔类型的变量,则可以直接作为if标识的判断条件,例如:

<#if animals.python.protected>
           
           
  Warning! Pythons are protected animals!
           
           
</#if>  
          
          

List标识

很显然,list用来显示一列表。例如,如果我们用下面这个模板展示上面的序列的数据的话:

<p>We have these animals:
           
           
<table border=1>
           
           
  <tr><th>Name<th>Price
           
           
  <#list animals as being>
           
           
  <tr><td>${being.name}<td>${being.price} Euros
           
           
  </#list>
           
           
</table>  
          
          

输入的内容如下:

<p>We have these animals:
           
           
<table border=1>
           
           
  <tr><th>Name<th>Price
           
           
  <tr><td>mouse<td>50 Euros
            
            
  <tr><td>elephant<td>5000 Euros
            
            
  <tr><td>python<td>4999 Euros
           
           
</table>  
          
          

标准的list标识的标签语法如下:

<#list sequence as loopVariable>repeatThis</#list>

repeatThis位置的数据将被循环输出,直至循环结束。我们可以在这个位置组织我们的数据。loopVariable作为局部变量,只存在于<#list ...></#list>标签中。

下一个例子中,我们列出所有的fruits数据:

<p>And BTW we have these fruits:
           
           
<ul>
           
           
<#list whatnot.fruits as fruit>
           
           
 <li>${fruit}
           
           
</#list>
           
           
<ul>  
          
          

表达式whatnot.fruits 我们现在应该知道它的含义了。

include 标识

使用include标识,我们可以将其他的内容加入到模板中来。

假设我们要在多个页面中展示相同的内容,我们可以创建一个关于这个内容的文件,之后将这个文件引入到每个要求展示的地方。例如,我们可以把版权声明信息单独提取出来,写入文件copyright_footer.html中:

<hr>
           
           
<i>
           
           
Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
           
           
<br>
           
           
All Rights Reserved.
           
           
</i>  
          
          

当我们需要展示版权声明时,在页面用include标识引入即可:

<html>
           
           
<head>
           
           
  <title>Test page</title>
           
           
</head>
           
           
<body>
           
           
  <h1>Test page</h1>
           
           
  <p>Blah blah...
           
           
<#include "/copyright_footer.html">
           
           
</body>
           
           
</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>  
          
          

如果我们修改copyright_footer.html文件,那么所有页面的版权信息将都会改变。

综合使用标识

我们可以根据页面的需要多次使用标识,而且标识之间也支持嵌套。例如,我们要列出所有animals并使用大一号的字体标识出size值为largeanimal的名称:

<p>We have these animals:
           
           
<table border=1>
           
           
  <tr><th>Name<th>Price
           
           
  <#list animals as being>
           
           
  <tr>
           
           
    <td>
           
           
      <#if being.size == "large"><font size="+1"></#if>
           
           
      ${being.name}
           
           
      <#if being.size == "large"></font></#if>
           
           
    <td>${being.price} Euros
           
           
  </#list>
           
           
</table>  
          
          

注意:FreeMaker将不会对运算符、标识和注释外的文字做任何操作,不会对font标签有任何影响。

对“无法找到”的变量的处理

在实际开发过程中,数据模型中存储的变量是无法预知的。对于没有明确标明的 “无法找到”的变量,FreeMaker无法正常运行。下面列出两种FreeMaker典型的处理方式:

提示:一个不存在的变量和一个null值的变量在FreeMaker看来都是一样的,因此我们用“无法找到”这个词来统一描述。

方法一:使用默认值。当我们引用一个变量时,我们可以设置这个变量的默认值,默认值在变量“无法找到”时生效,方法是在变量后用“!”操作符将变量与默认值连接。像下面的例子,当user变量在数据模型中“无法找到”时,模板将认为user的值为"Anonymous"

<h1>Welcome ${user!"Anonymous"}!</h1>  
          
          

方法二:用if标识判断。我们可以在使用变量之前用if标识判断变量是否“无法找到”,具体格式是在if标签中的条件位置上引用变量名,并用“??”连接,如:

<#if user??><h1>Welcome ${user}!</h1></#if>  
          
          

关于多层变量的访问方式,如animals.python.price表达式 animals.python.price!0 只有在 animals.python存在的条件下才是正确的。 只有在最后一个变量“无法找到”时,这里的“!”操作符才生效(python也可能“无法找到”),因此这种情况下,我们在赋默认值时应该使用下面的格式: (animals.python.price)!0。同样的,在if标识中??操作符应这样使用: (animals.python.price)??.

 

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值