最简单的模版就是纯HTML文件(或者其他任何文本文件,FreeMarker并不局限于HTML)。当客户端访问这个页面时,FreeMarker会发送这个html到客户端。当然你希望页面是更加动态时,你把FreeMarker能理解的部分加入到HTML中:
- ${...}:FreeMarker在输出中会用实际值替换大括号中的表达式。这些叫interpolation内插值。见第一个例子。
- FTL 标签(FreeMarker 模版语言标签):FTL标签和HTML标签类似,但是这些标签只是FreeMarker的指令,不会在结果中输出。这些标签都由“#”开始(用户自定的FTL标签由“@”开始,而不是”#”,但是这些是高级主题,见后续翻译)。
- 注释:模版注释和html注释类似,但是是由<#-- 和 -->标记。这两个界定符之间的任何东西包括界定符本身都会被FreeMarker忽略,不会在结果中输出。
除内插值、FTL标签和注释之外的任何值,都被认定为静态文本,不会被FreeMarker翻译,按原样输出。
FTL标签涉及到所谓的指令。这里的关系如同HTML标签(例如:和<table></table>)和HTML元素(如table元素)之间的关系。(如果你没有感觉到这里的不同,尽管将FTL标签和指令当做同义词吧,没有关系)
指令举例
尽管FreeMarker包含很多指令,但是在这个初步预览里,我们只举三个最常用的指令作为例子。
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>
这里你告诉FreeMarker,字符串", our beloved leader"仅当变量user的值为"Big Joe"时才会被输出。总的来说,<#if condition>和</#if>之间的内容会被跳过,如果condition值为假的话。
让我们详细地看一下这里的条件:user == "Big Joe"。==是测试左右两边是否相等的操作符,运算结果是一个布尔值,true或者false。在==的左边,我们引用了一个变量,比较时会使用实际值代替。总的来说,在指令或者内插值当中没有引号标记的词FreeMarker都会当做变量来使用。在==的右边,我使用了一个字符串,字符串在模版中必须用引号标记。
如下: 如果price为0的话,会打印"Pythons are free today!":
<#if animals.python.price == 0>
Pythons are free today!
</#if>
类似于刚才直接使用字符串,这里的数字也可以直接使用,注意数字不需要加引号,如果你使用”0”,FreeMarker会将它理解为字符串.
如下: 如果price非0的话,会打印"Python 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>
使用<#else>标签,我们指定当condition为假时该做什么.例如:
<#if animals.python.price < animals.elephant.price>
Pythons are cheaper than elephants today.
<#else>
Pythons are not cheaper than elephants today.
</#if>
这个会打印”Pythons are cheaper than elephants today.” 如果python的价格小于elephant的价格,反之则打印”Pythons are not cheaper than elephants today.”
如果你有个包含布尔值的变量(true或者false),你可以直接根在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>标签之间(作用域在这两者之间,之外则不可见).
作为另一个例子,我们列出数据模型例子中的所有fruit:
<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,访问者会在所有页面看到新的版权信息.
使用多个指令
你可以在页面中任意多次地使用指令,并且你可以切套地使用指令,正如你可以在HTML标签中切套地使用其他HTML标签.例如下例会列出所有的animal,并使用粗体打印他们的名字:
<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>
注意这里,因为FreeMarker不对FTL标签,内插值和注释之外的文本翻译,它不会看到上面内嵌的font标签.
处理缺失变量
在实践中,数据模型经常有一些可选的变量(例如,有时候就是未定义).为防止典型的人为错误,FreeMarker不容忍对缺失变量的引用,除非你明确指明如果变量缺失时该做何处理.这里我们会展示两种最典型的处理方法.
给编程人员的提示:一个不存在(未定义)的变量和一个变量但是包含null值,对FreeMarker来说是一样的.所以这里”缺失”一词包含了这两种情况.
无论何时,我们引用一个变量时,我们都可以指定一个默认值,当这个变量缺失时,使用的时候在变量后跟”!”和默认值.如下例中,当user在数据模型中缺失时,模版会使用字符串”Anonymous”代替user.(当user在数据模型中有定义且不为null时,模版会只用准确的值,而”Anonymous”好像不曾在那里一样):
<h1>Welcome ${user!"Anonymous"}!</h1>
你可以在变量名后跟两个问号??来检测变量是否缺失.结合已介绍的if指令你可以跳过整个问候如果user变量缺失的话:
<#if user??><h1>Welcome ${user}!</h1></#if>
对于多步访问的变量,如animals.python.price,animals.python.price!0仅当animals.python都不缺失并且只有最后一个子变量price,可能缺失(在这种情况下值为0)的时候才是正确的.如果animals或者python缺失,模版处理过程会因”未定义变量”错误而停止.为防止出现这种情况,你需要这样写(animals.python.price)!0,加了括号之后,在这种情况下,表达式的值会为0,如果animals或者python缺失的话.同样的逻辑对??(测试运算符)也成立: animals.python.price??和(animals.python.price)??的情况和上面说的一样.
没有评论:
发表评论