`

freemarker之模板开发(其它之命名空间)

 
阅读更多

freemarker之模板开发(其它之命名空间)

-----------

1.简介

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

如果想创建可以重复使用的宏,函数和其他变量的集合,通常用术语来说就是引用library 库。使用多个命名空间是必然的。只要考虑你在一些项目中,或者想和他人共享使用的时候,你是否有一个很大的宏的集合。但要确保库中没有宏(或其他变量)名和数据模型中变量同名,而且也不能和模板中引用其他库中的变量同名。通常来说,变量因为名称冲突也会相互冲突。所以要为每个库中的变量使用不同的命名空间。

 

2.创建一个库

我们来建立一个简单的库。假设你需要通用的变量copyright 和mail(在你疑问之前,宏当作是变量):

<#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 中使用这个模板。如果在aWebPage.ftl 使用<#include "/lib/my_test.ftl">,那么就会在主命名空间中创建两个变量,这样就不是很好,因为想让它们只在同一个命名空间”My Test Library”中。所以就不得不使用import 指令来代替include 了。乍一看,这个指令和include 很相似,但是它会为lib/my_test.ftl 创建一个空的命名空间, 然后在那里执行。

lib/my_test.ftl 会发现它自己在一个新的环境中,那里只有数据模型的变量可以来呈现(因为它们在那里面都是可见的),然后会在这个环境中创建两个变量。现在来看这很不错,但是如果想访问aWebPage.ftl 中的两个变量,而它们使用的是主命名空间,就不能看到其他命名空间中的变量。解决方法是import 指令不仅仅创建命名空间,而且要通过import 的调用者(本例中的主命名空间)创建一个新的哈希表变量,这就成为进入新的命名空间的大门。那么aWebPage.ftl 就像下面这样: 

<#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

 

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

不要忘了在模板的命名空间(可以使用assign 或macro 指令来创建的变量)中的变量有着比数据模型中的变量更高的优先级。因此,数据模型的内容不会干涉到由库创建的变量。

注意

在通常一些应用中,你也许想在模板中创建所有命名空间都可见的变量,就像数据模型中的变量一样。但是你不能在模板中改变数据模型,却可以通过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,一个单一模板执行工作的内容都是这样。   

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics