2009年4月13日星期一

FreeMarker中文手册--KLW 模版 + 数据模型 = 输入

模版 + 数据模型 = 输入

假设你需要一个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”)应该依赖于谁登录进这个页面,而最新商品应该从数据库中读取,因此潜在地,这些内容是经常改变的。在这种情况下,我们不能直接在HTML中输入用户名、URL和最新商品的名字,换句话说,我们不能使用静态HTML。

对这个问题的解决办法,FreeMarker使用一个模版,而不是静态HTML页面。这个模版和静态页面类似,除了它包含一些指令(让FreeMarker将页面变成动态的):

<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html>

这个模版存储在web服务器上,就像静态HTML页面一样。但是,无论谁访问这个页面时,FreeMarker会即使介入并翻译这个模版,把所有的 ${...}替换成最新的内容(比如,将${user} 替换成“Big Joe”或者其他登录者的用户名),然后把结果发送给访问者的Web浏览器,所以访问者的浏览器会接收到像第一个例子中的HTML页面(纯HTML没有FreeMarker指令),不会察觉到服务器已经使用了FreeMarker。模版文件本身(存储在服务器端)不会改变。这个翻译过程对每次访问都会发生。这保证了显示的信息总是最新的。

现在,你也许已经注意到模版没有包含任何指令来找出谁是当前访问者,或者查询数据库获得最新产品。它看起来好像已经知道这些值。而实际上,这里隐藏了一个FreeMarker的重要思想(实际上是MVC的),显示逻辑和业务逻辑应该分离。在模版中只处理显示相关的事情,比如可视的图样、格式等。显示的数据(如用户名等)在FreeMarker之外准备,比如经常用java语言或者其他通用语言。所以模版作者不用知道这些值是如何计算的。实际上,这些值的计算方法可以完全改变,而模版仍可保持不变,同样,不改变其他任何东西只修改模版可使页面外观完全改变。当模版设计者和编程人员是不同人时这种分离会格外有用。

当FreeMarker(和模版作者)不关心数据是如何计算的时候,FreeMarker仍需知道实际数据是什么。所有在模版中使用的数据,都可以归入所谓的数据模型。这个数据模型由已经提到的Java等常规性语言计算。对模版作者而言,数据模型是一个树状结构(如你硬盘上的目录和文件)。在这个例子中,直观地表示如下:


(root)
|
+- user = "Big Joe"
|
+- latestProduct
|
+- url = "products/greenmouse.html"
|
+- name = "green mouse"

(为防止误解:数据模型并不是文本文件,以上只是直观的展示树状。它从java对象中来,但把这个问题留给java编程人员吧。)

把这个和你之前看到的模版相比较,${user}和${latestProduct.name}。类似地,数据模型像计算机的文件系统,root和latestProduct对应目录,而user, url 和 name对应文件。url和name在latestProduct目录下。所以latestProduct.name指的是在latestProduct目录下的name文件。这只是个类比,这里没有目录和文件。

总而言之,模版和数据是FreeMarker生成输出时需要的:
模版 + 数据模型 = 输出

没有评论: