您的位置:首页 > 运维架构 > 网站架构

[FreeMarker 2.3.20] Part I 关于模版设计的介绍 ~模板~架构总览、指令

2014-03-23 22:15 381 查看
    Note

    这个章节是假设你已经阅读过前边的开始部分值部分和类型部分

模板架构总览

事实上模板是你用FTL
(FreeMarker Template Language的缩写) 语言所写的程序。它只是一个专门为写模板而设计的简单程序语言

一个模板文件 (= FTL program) 是以下几个部分的混合物:

文本: 文本会被原样输出

插值: 在输出文件中这些部分会被计算的值所替代。插值是以 ${和 }来表示的。 (或者是#{和 }, 但这个已经不再使用。参见这里,链接后续添上)

FTL tags: FTL 标签和 HTML 标签有点类似,但是它们是 FreeMarker 的指令而且是不会被输出到文件的。

注释: 这部分也同 HTML 的注释,不过它们是以 <#-- 和 -->划分的。注释会被 FreeMarker 忽略掉且不会输出到文件中。
让我们看一个具体的例子吧。 我已经对模板的各个组成部分用颜色标注了:
文本,插值,FLT 标签,注释。 [BR]-s主要是为了识别换行。

<html>[BR]
<head>[BR]
  <title>Welcome!</title>[BR]
</head>[BR]
<body>[BR]
  <#-- Greet the user with his/her name -->[BR]
  <h1>Welcome ${user}!</h1>[BR]
  <p>We have these animals:[BR]
  <ul>[BR]
  <#list animals as being>[BR]
    <li>${being.name} for ${being.price} Euros[BR]
  </#list>[BR]
  </ul>[BR]
</body>[BR]
</html>


FTL 是识别大小写的,因此 list 是个正确的指令名称,而
List 却不是。同样 ${name} 、${Name}、${NAME}三者是不同的。

这里要特别注意的是插值是只能用在文本部分的 (或者字符常量中;见后边内容,链接后续添上)。

一个 FTL 标签不能写在另一个 FTL 标签里边,也不能写在一个插值里边。比如这样就是错误的:<#if <#include 'foo'>='bar'>...</#if>

不过注释是可以在 FTL 标签和插值里边的。比如下例:

<h1>Welcome ${user <#-- The name of user -->}!</h1>[BR]
<p>We have these animals:[BR]
<ul>[BR]
<#list <#-- some comment... --> animals as <#-- again... --> being>[BR]
...


    Note

    如果你们尝试了上边例子的开发者们:你们可能已经注意到里边的一些空格,tabs,换行在输出文件中消失了,即使我们之前有说过文本部分会原样输出的。不用再苦恼了。这里有个"空白移除" ("white-space stripping") 功能被打开了,这样会自动的移除掉一些多余的空格,tabs,换行符。这个会后续解释的。

指令

你是用的 FTL 被叫做指令 (directives).在例子中你已经调用过list指令了。从语法上来说这个指令的调用是通过 <#list animals as being >和</#list>完成的。

这里有两种 FTL 标签:
开始标签: <#directivename parameters>
结束标签:</#directivename>

除了名字是以 # 开始的外,其他语法方面是与 HTML 和 XML 类似的。如果指令是没有嵌套内容的(处于开始标签和结束标签的那部分内容),那么你就只能写开始标签而不能有结束标签(这里应该是可以有结束,毕竟嵌套部分也可以是空白)。比如说,你写了<#if something> ... </#if>,<#include
something> ( 这里应该是由一个斜杠的,像这样<#include something/>,貌似是原文中少了,要不然就很难判断这个开始标签是否还有结束标签来搭配),但是 FreeMarker 只会识别出include指令不包含嵌套内容。

parameters 的格式由 directivename来决定。

事实上是有两种指令:预定义指令(系统定义指令)和自定义指令。在自定义指令中会用@ 来代替
#。比如,<@mydirective parameters> ... </@mydirective>. 还有个不同的是在不包含嵌套内容的标签中的标签格式如:<@mydirective parameters />(这里不包含嵌套内容的标签格式和上边提到的预定义标签格式还是有区别额,一个有后斜杠,一个没有,对于上边我的注释待我实践后进行更正,或者有了解的读者还请提出,不胜感激
:)),如同 XML 中的格式(e.g. <img ... />). 不过自定义指令是一个高级主题将会在后边讨论。

FTL 标签和 HTML 标签一样必须要有正确的嵌套匹配。所以以下的代码是错误的,if 指令在嵌套标签list指令t的里边和外边。
<ul>
<#list animals as being>
<li>${being.name} for ${being.price} Euros
<#if user == "Big Joe">
(except for you)
</#list> <#-- WRONG! The "if" has to be closed first. -->
</#if>
</ul>


不过 FreeMarker 并不会关心嵌套的 HTML 标签,只会关心 FTL 标签。它只是将 HTML 标签看作普通的文本,不会对它进行解析。

如果你使用了一个不存在的指令 (e.g. 你打错了指令的名称), FreeMarker 将会拒绝继续使用模板并且会抛出一个错误信息(FreeMarker will decline to use the template and ...)。

FreeMaker 会忽略 FTL 标签内容的多余空格。所以你可以这样写:

<#list[BR]
  animals       as[BR]
     being[BR]
>[BR]
${being.name} for ${being.price} Euros[BR]
</#list    > 


你或许不会在 < 或</ 与指令名称之间插入空格(这里没弄清是不太能或者是不能,待实践后补上,或者麻烦读者给翻译下这个句子,You may not, howeve, ...,不胜感激 :))。

所有的指令列表和介绍信息可以在手册~指令手册处找到(不过我推荐首先看一下关于表达式的章节)

    Note

    在 FreeMarker 中的FTL 标签和 FTL 注释中是可以通过配置将 < 和> 替换为[和 ],就像这样: [#if user == "Big Joe"] ...
[/#if]. 更多信息可阅读这里:杂项~可选(方括号)语法(此处链接待后续翻译完添上)

    Note

    FreeMarker 也可以配置成预定义标签中不包含 #(比如 <if user == "Big Joe"> ... </if>).但是我们不推荐使用这种方式。更多信息可以参见这里:(手册~不赞成使用的 FTL 功能 (construts,没有很好的翻译)~老的 FTL 语法,此处链接待后续翻译完成后添上)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息