文章图片标题

freemaker模板技术之模板

分类:模板引擎 作者:阳光倾城 评论:0 点击: 664 次 日期:2015-07-29

模板元素

最简单的模板是普通文本(比如常用的HTML 文件) 。当客户端访问页面时,FreeMarker 要发送 HTML 代码至客户端浏览器端显示。如果
想要页面动起来,就要在 HTML 中放置能被 FreeMarker理解并解析的特殊部分。

${…}:FreeMarker 将会输出真实的值来替换花括号内的表达式,这样的表达式被称为
interpolations 插值(和jsp里面的EL表达式一路的)。

FTL tags 标签(FreeMarker  模板的语言标签) :FTL 标签和 HTML 标签有一点相似,但是
它们是 FreeMarker 的指令而且是不会直接输出出来的东西。这些标签的使用一般以符号#
开头。(用户自定义的 FTL 标签使用@符号来代替#)

Comments 注释:FreeMarker 的注释和 HTML 的注释相似,但是它用<#--和-->来分
隔的。任何介于这两个分隔符(包含分隔符本身)之间内容会被 FreeMarker 忽略,就不会
输出出来了。

其他任何不是 FTL 标签,插值或注释的内容将被视为静态文本,这些东西不会被
FreeMarker 解析,会被按原样输出。

directives 指令:就是 FTL 标签。这些指令与 HTML 的标签 和 HTML 元素的关系是相同的。

三个最常用的指令:

1. if指令

不解释,和开发中用到的那个if一样,你懂得:

<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>
Welcome ${user}<#if user == "Mr Zhang">, 我们的大boss</#if> !
</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html> 

在这里, 我们告诉 FreeMarker ,我们尊敬的领导才是 if 条件中那唯一的 user 变量值,
当它和“Mr Zhang”相同时才显示。当 condition 的判断结果为 false时,在<#if condition>和</#if>标签之间的内容会被略过。
我们来详细说说 condition(条件表达式) 的使用:==是来判断在它两侧的值相等的操作符,比较的结
果是布尔值,true 或者 false。在==的左侧,是引用的变量,我们很熟悉这样的语法,它会
被变量的值来替代。右侧是指定的字符串,在模板中的字符串必须放在引号内。

当 price 是 0 的时候,下面的代码将会打印:”Pythons are free today!”

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

和前面的示例相似,字符串被直接指定,但是这里则是数字(0)被直接指定。注意到
数字是不用放在引号内的。如果将 0 放在引号内(”0”),FreeMarker 就会将其误判为字符
串了。
当 price 不是 0 的时候,下面的代码将会打印:”Pythons are not free today!”

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

也可以这样来写代码(使用数据模型来描述哈希表变量) :

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

这其实是名称空间的具体应用,也是freemaker的强大之处。

使用<#else>标签可以指定当条件为假时程序执行的内容。例如:

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

如果蟒蛇的价格比大象的价格低,将会打印”Python are cheaper than elephants today.”,
否则就打印”Pythons are not cheaper than elephants today.”
如果变量本身就是布尔值(true 或者 false ),那么 可以直接让其作为 if 的条件
condition:

<#if animals.python.protected>
Warning! Pythons are protected animals!
</#if> 
这和js、Java等编程语言是完全一致的。

2.list指令

这个是用来遍历集合元素的,就是那个Java里的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>

模板引擎解释以后会生成如下的html:

<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 部分将会在给定的 sequence 遍历时在每项中重复,从第一项开始,
一个接着一个。在所有的重复中,loopVariable 将持有当前项的值。这个循环变量仅
存在于<#list …>和</#list>标签之间。
再看一个示例,遍历示例数据模型 fruits。

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

3.include指令

使用 include 指令,我们可以在当前的模板中包含其他文件的内容。这和jsp静态包含的语法一样。
要在一些页面中显示版权声明的信息。可以创建一个文件来单独包含版权声明,
之后在需要它的地方插入即可。比方说,我们可以 将版权信息单独 存放在页面文件
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:

<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>

 

总结:在编制模板时可以联合使用各种指令,可以相互嵌套,和html标签的嵌套使用一样。下面的实例会遍历动物集合,并使用大一号的字体打印大型动物的名字。

<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 从数据模型中丢失时,模板将会将
user 的值表示为字符串”Anonymous”。(若 user 并没有丢失,那么模板就会表现
出”Anonymous”不存在一样):

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

当然也可以在变量名后面通过放置??来询问 FreeMarker 一个变量是否存在。将它和 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。这种情况下当 animals 或
python 不存在时表达式的结果仍然是 0 。对于??也是同样用来的处理这种逻辑的:
animals.python.price??对比(animals.python.price)??来看。




声明: 除非注明,本文属( 阳光倾城 )原创,转载请保留链接: http://www.tomrrow.com/archives-3000.html