freemarker 命名空间

1 简单介绍

当执行 FTL 模板时,就会有使用 assign 和 macro 指令创建的变量的集合(可能是空的),能够从前一章节来看怎样使用它们。像这种变量集合被称为 namespace 命名空间。在简单的情况下能够仅仅使用一个命名空间,称之为 main namespace 主命名空间。由于通常仅仅使用本页上的命名空间,所以就没有意识到这点。


假设想创建能够反复使用的宏,函数和其它变量的集合,通经常使用术语来说就是引用library 库。使用多个命名空间是必定的。仅仅要考虑你在一些项目中,或者想和他人共享使用的时候,你是否有一个非常大的宏的集合。但要确保库中没有宏(或其它变量)名和数据模型中变量同名,并且也不能和模板中引用其它库中的变量同名。通常来说,变量由于名称冲突也会相互冲突。

所以要为每一个库中的变量使用不同的命名空间。


2 创建一个库

<#macro copyright date>
<p>Copyright (C) ${date} Julia Smith. All rights reserved.</p>
</#macro>
<#assign mail = "jsmith@acme.com">
把上面的这些定义存储在文件 lib/my_test.ftl 中(文件夹是你存放模板的位置)。
如 果 在 aWebPage.ftl 使 用<#include "/lib/my_test.ftl"> ,那么就会在主命名空间中创建两个变量,这样就不是非常好,由于想让它们仅仅在同一个命名空间”My Test Library”中。所以就不得不使用import 指令来取代 include 了。乍一看,这个指令和 include 非常相似,可是它会为 lib/my_test.ftl 创 建 一 个 空 的 命 名 空 间 , 然 后 在 那 里 执 行 。


<#import "/lib/my_test.ftl" as my>
<#-- 被称为"my"的哈希表就会是那个"大门" -->
<@my.copyright date="1999-2002"/>
${my.mail}
import 指令不只创建命名空间,并且要通过 import 的调用者(本例中的主命名空间)创建一个新的哈希表变量,这就成为进入新的命名空间的大门。

<#import "/lib/my_test.ftl" as my>
<#assign mail="fred@acme.com">
<@my.copyright date="1999-2002"/>
${my.mail}
${mail}
<p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.
<br>Email: jsmith@acme.com</p>
jsmith@acme.com
fred@acme.com

3 在引入的命名空间上编写变量
偶尔想要在一个被包括的命名空间上创建或替换一个变量。那么能够使用 assign 指令在完毕,假设用到了它的 namespace 变量,比如以下这样:

<#import "/lib/my_test.ftl" as my>
${my.mail}
<#assign mail="jsmith@other.com" in my>
${my.mail}
jsmith@acme.com
jsmith@other.com

4 命名空间和数据模型
数据模型中的变量在不论什么位置都是可见的。

假设在数据模型中有一个名为 user 的变量,那么 lib/my_test.ftl 也能訪问它, aWebPage.ftl 当然也能。

<#macro copyright date>
 <p>Copyright (C) ${date} ${user}. All rights reserved.</p>
</#macro>
<#assign mail = "${user}@acme.com">
假设 user 是”Fred”的话,以下这个样例:
<#import "/lib/my_test.ftl" as my>
<@my.copyright date="1999-2002"/>
${my.mail}
<p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>
Fred@acme.com

注意:
在通常一些应用中,你或许想在模板中创建全部命名空间都可见的变量,就像数据模型中的变量一样。可是你不能在模板中改变数据模型,却能够通过 global 指令来达到相似的效果

5 命名空间的生命周期

命名空间由使用的 import 指令中所写的路径来识别。

假设想多次 import 这个路径,那么仅仅会为第一次的 import 引用创建命名空间运行模板。后面同样路径的 import仅仅是创建一个哈希表当作訪问同样命名空间的“门”。比如,在 aWebPage.ftl 中:

<#import "/lib/my_test.ftl" as my>
<#import "/lib/my_test.ftl" as foo>
<#import "/lib/my_test.ftl" as bar>
${my.mail}, ${foo.mail}, ${bar.mail}
<#assign mail="jsmith@other.com" in my>
${my.mail}, ${foo.mail}, ${bar.mail}
jsmith@acme.com, jsmith@acme.com, jsmith@acme.com
jsmith@other.com, jsmith@other.com, jsmith@other.com
这里能够看到通过 my , foo 和 bar 訪问同样的命名空间。


还要注意命名空间是不分层次的,它们相互之间是独立存在的。那么,假设在命名空间N1 中 import 命名空间 N2,那 N2 也不在 N1 中,N1 仅仅是能够通过哈希表来訪问 N2。这和在主命名空间中 import N2,然后直接訪问命名空间 N2 是一样的过程。
每一次模板的运行过程,它都有一个私有的命名空间的集合。每一次模板运行工作都是一个分离且有序的过程,它们只存在一段非常短的时间,同一时候页面用以呈现内容,然后就和全部填充过的命名空间一起消失了。

因此,不管何时我们说第一次调用 import ,一个单一模板运行工作的内容都是这样。

6 为他人编写库
为了防止和其它作者使用库的命名相冲突,并且引入其它库时要书写简单,这有一个其实的标准,那就是指定库路径的格式。这个标准是:库的路径必须对模板和其它库可用(可引用),就像这样:

/lib/yourcompany.com/your_library.ftl

假设你为 Example 公司工作,它们拥有 www.example.com 网的主页,你的工作是开发一个部件库,那么要引入你所写的 FTL 的路径应该是:
/lib/example.com/widget.ftl

注意到 www 已经被省略了。第三次路径切割后的部分能够包括子文件夹,能够像以下这样写:

/lib/example.com/commons/string.ftl

一个重要的规则就是路径不应该包括大写字母,为了分隔词语,使用下划线 _ ,就像wml_form (而不是 wmlForm )。


posted on 2017-08-13 17:55  wgwyanfs  阅读(169)  评论(0编辑  收藏  举报

导航