首页 > 代码库 > freemarker 命名空间
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 )。