当运行FTL模版时,就会有使用assign和macro指令创建的变量的集合(可能是空的),像这样的变量集合被称为namespace命名空间。在简单的情况下可以只使用一个命名空间,称之为main namespace主命名空间。
如果想创建可以重复使用的宏,函数和其他变量的集合,通常用术语来说就是引用library库。
- 创建一个库
<#macro copyright date>
<p>Copyright (C) ${date} Julia Smith. All rights reserved.</p>
</#macro>
<#assign mail = "jsmith@acme.com">
<#import "/lib/my_test.ftl" as my>
<#-- 被称为"my"的哈希表就会是那个"大门" -->
<@my.copyright date="1999-2002"/>
${my.mail}
要注意它是怎么访问为 lib/my_test.ftl 创建的命名空间中的变量的,通过新创 建的哈希表,my。那么将会打印出:
<p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.</p>
jsmith@acme.com
如果在主命名空间中有一个变量,名为 mail 或copyright,那么就不会引起混乱 了,因为两个模板使用了不同的命名空间。例如,在 lib/my_test.ftl 中修改 copyright 成如下这样:
<#macro copyright date>
<p>Copyright (C) ${date} Julia Smith. All rights reserved.
<br>Email: ${mail}</p>
</#macro>
然后修改 aWebPage.ftl 中的内容:
<#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
当调用了 copyright 宏之后,输出和上面的是相似的,因为 FreeMarker 已经暂时转 向由 import 指令为/lib/my_test.ftl 生成的命名空间了。因此,copyright 宏看到在主命名空间中变量 mail 存在,而且其他的mail 不存在。
偶尔想要在一个被包含的命名空间上创建或替换一个变量。那么可以使用 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
- 命名空间和数据模型
数据模型中的变量在任何位置都是可见的。如果在数据模型中有一个名为 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
不要忘了在模板的命名空间(可以使用 assign 或 macro 指令来创建的变量)中的 变量有着比数据模型中的变量更高的优先级。因此,数据模型的内容不会干涉到由库创建的 变量。
- 命名空间的生命周期
命名空间由使用的 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
还要注意命名空间是不分层次的,它们相互之间是独立存在的。那么,如果在命名空间 N1 中 import 命名空间 N2,那 N2 也不在 N1 中,N1 只是可以通过哈希表来访问 N2。这 和在主命名空间中 importN2,然后直接访问命名空间 N2 是一样的过程。