freemark 应用以及优点

在B/S程式设计中,经常有美工和程序员二个角色,他们具备不一样专业技能:美工专一于表现——建立页面、风格、布局、效果等等可视元素;而程序员则忙于建立程式的商业流程,生成设计页面要显示的数据等等。不少时候,要显示的资料在设计的时候并不存在,它们通常是在运行时由程式产生的,好比执行“价格不高于800NT的USB Disk”查询的返回结果。这种技术需求产生了JSP等Scriptlet,JSP十分强大,可是也经常被滥用,并致使一些不良的后果

将逻辑和表现混合在一块儿。
破坏了美工和程序员职责的正常分解。
使JSP页面难以阅读和维护。
模板引擎就是为了解决上面的问题而产生的。在设计HTML的时候,咱们加入一些特定指令来指定要插入哪些数据,这些加了特殊指令的HTML或者其余文本,咱们称为模板(Template)。而模板引擎会在输出页面时,用适当的数据替代这些代码。
模板和嵌入JSP的HTML是不一样的,模板指令只有颇有限的编程能力,能够避免混入商业逻辑。
三万英尺俯瞰FreeMarker
简单的说,FreeMarker就是一种用Java编写的模板引擎,它根据模板输出多种规格的文本。特别指出的是,FreeMarker与Web应用框架无关,它一样能够应用在非Web应用程序环境中。

下面咱们来看看FreeMarker的模板:(product.ftl)

<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中加入了一些由${…}包围的特定代码,这些特定代码就是FreeMarker的指令。

至于user、latestProduct.url和latestProduct.name的具体内容则来自于数据模型(data model)。数据模型由程序员编程来建立,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成。

模板设计者不关心数据从那儿来,只知道使用已经创建的数据模型。

借助FMPP(FreeMarker PreProcessor)来运行FreeMarker
首先说明的是FreeMarker的运行并不依赖于FMPP。FMPP只是一个FreeMarker的辅助工具,有了它,咱们能够快速地调试FreeMarker输出结果,而不须要借助Java编程,这能够大大地减轻美工设计人员的调试难度。

在磁盘上创建相关的文件夹:

D:/work/src/product.ftl

D:/work/out/

D:/work/data/product.tdd

D:/work/config.fmpp
咱们使用的配置文件(config.fmpp)设置以下:

sourceRoot: src

outputRoot: out

logFile: log.fmpp

modes: [

copy(common/**/*.*, resource/*.*)

execute(*.ftl)

ignore(templates/*.*, .project, **/*.xml, xml/*.*, *.js)

]

replaceExtensions: [ftl, html]

sourceEncoding: gb2312

data: tdd(../data/product.tdd)
注意:"data: tdd(../data/product.tdd)" 指定了模板的数据源,TDD是fmpp支持的数据格式之一 ,关于TDD介绍可参阅fmpp文档,也可参看TDD 。product.tdd内容是这样的:

{

user: "Big Joe"


latestProduct: {url: "products/greenmouse.html"
, name: "Green Mouse"
}

}
如今在dos下执行(假设FMPP安装在D:/FMPP下):

D:/work/>D:/FMPP/bin/fmpp
最后的输出结果是这样的,存放在文件out/product.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>
正如FreeMarker文档中所叙述的,FreeMarker的工做原理就是:

模板+数据=输出!

FreeMarker并不局限于生成html,甚至能够产生java代码,这仅仅取决于你如何设计模板而已。

如今有了FMPP这个强大工具,咱们接下来能够快速学习FreeMarker的相关指令。let us go!

在FreeMarker模板中使用的三种基本对象类型:Scalars、Hashes 和Sequences。在解释这些对象类型以前,咱们先来看看数据模型。

典型的数据模型是树型结构,能够有任意深的层次,好比说:

(root)

  |

  +- animals

  |   |

  |   +- mouse

  |   |   |  

  |   |   +- size = "small"


  |   |   |  

  |   |   +- price = 50

  |   |

  |   +- elephant

  |   |   |  

  |   |   +- size = "large"


  |   |   |  

  |   |   +- price = 5000

  |   |

  |   +- python

  |       |  

  |       +- size = "medium"


  |       |  

  |       +- price = 4999
这棵树上的每一片叶子在FreeMarker中就称为Scalars,用来存储单值。Scalars保存的值 有两种类型:字符串(用引号括起,能够是单引 号或双引号)、数字(不要用引号将数字括起,这会做为字符串处理)、日期和boolean值。对scalars的访问要从root开始,各部分用“.”分 隔,如animals.mouse.price。

树的每个分支关联一个惟一的查询名字,例如“mouse”,“elephant”,这些分支充当了其余对象(size,price)的容器,这种结构则称为Hashes,参考Hashes的TDD定义 。

Sequences的做用与Hashes相似,也能够充当其它对象的容器,只是不使用变量名字,而使用数字索引:

(root)

  |

  +- animals

  |   |

  |   +- (1st)

  |   |   |

  |   |   +- name = "mouse"


  |   |   |

  |   |   +- size = "small"


  |   |   |

  |   |   +- price = 50

  |   |

  |   +- (2nd)

  |   |   |

  |   |   +- name = "elephant"


  |   |   |

  |   |   +- size = "large"


  |   |   |

  |   |   +- price = 5000

  |   |

  |   +- (3rd)

  |       |

  |       +- name = "python"


  |       |

  |       +- size = "medium"


  |       |

  |       +- price = 4999
能够经过animals[0].name来访问相应的Scalars。参考Sequences的TDD定义

针对上面三种对象类型的操做,能够参看对象类型的各类操做

模板与指令
除了相关的文本外,在FreeMarker模板中能够包括下面三种特定部分:

${…}:称为插补(interpolations),FreeMarker会在输出时用实际值进行替代。
指令:也叫FreeMarker标记,与HTML标记相似,但用#开始(有些以@开始 ,在后面叙述)。
注释:包含在<#-- 和 -->(而不是<!--和-->)之间文本。
控制指令
if指令
if指令与大部分程式语言同样,也支持<#else if..>,再也不赘述。

<#if
animals.python.price < animals.elephant.price>

  Pythons are cheaper than elephants today.

<#else
>

  Pythons are not cheaper than elephants today.

</#if
>
list指令
list指令将遍历Sequences里的每个元素。list指令有两个隐含的特殊变量:

item_index 该变量将返回元素在Sequences里的索引值。
item_has_next 该变量是boolean型,false代表该元素是Sequences里的最后一个元素。
<p>We have these animals:

<table border=1>

  <tr><th>Id<th>Name<th>Price

  <#list animals as being>

  <tr><td>${being_index+1}<td>${being.name}<td>${being.price} Euros

  </#list>

</table>
上面的模板能够依次列印出三种动物的名字和价格,being_index和being_has_next则是它的特殊变量。

能够用<#break>指令提早结束list循环。

switch指令
与其余语言的switch语句相似。

<#switch
being.size>

  <#case
"small"
>

     This will be processed if
it is small

     <#break
>

  <#case
"medium"
>

     This will be processed if
it is medium

     <#break
>

  <#case
"large"
>

     This will be processed if
it is large

     <#break
>

  <#default
>

     This will be processed if
it is neither

</#switch
>
注意事项
FTL区分大小写,因此list是正确的FTL指令,而List不是;${name}和${NAME}是不一样的
Interpolation只能在文本中使用
FTL标记不能位于另外一个FTL标记内部。
注释能够位于FTL标记和Interpolation内部。
多余的空白字符会在模板输出时移除
可用[#if..]来替代<#if..>,避免于HTML标记混淆。 html

相关文章
相关标签/搜索