Velocity的中文指南(2)-整理

类别:Java 点击:0 评论:0 推荐:
1.       取得语义Getting literal

VTL 特别的字符,比如$ 和 #, 来做这个工作,因此在模板中使用这些自负的时候必须格外小心。本节讲述$ 的转义。

1.1.     货币

我们写下句子 "I bought a 4 lb. sack of potatoes at the farmer's market for only $2.50!" ,这并没有什么问题。但如前所述,VTL标识符总是以大写或是小写字母开始,所以$2.50 在引用中将不能出错。

1.2.       转义有效的VTL 引用

问题将会出现,因为Velocity 将有一个潜在的冲突。转义特殊字符是处理VTL模板种特殊字符的最好的办法,者可以用一个反斜线来进行。

foo

$email

\foo

\$email

 

如果 Velocity 在VTL模板中遇到一个$email引用,他将在上下文中查找相应的值。这里,输出将是foo,因为 $email 是定义了的。如果$email 未定义,输出将是$email 。

 

假设$email 是定义了的(比如,具有值foo),但是你想输出 $email。可以有几种方法来做这个事情,不是最简单的是使用转义符。

## The following line defines $email in this template:

#set( $email = "foo" )

$email

\$email

\\$email

\\\$email

 

将输出是

foo

$email

\foo

\$email

 

注意: \ 绑定在$ 的左边。从做绑定原则使\\\$email 被解释为\\$email。 和上面例子比较下面的例子,这里$email 未定义。

$email

\$email

\\$email

\\\$email

输出

 

$email

\$email

\\$email

\\\$email

 

注意,Velocity 处理定义和未定义的引用是不同的。下面一个set 指令将$foo 设为值gibbous.。

#set( $foo = "gibbous" )

$moon = $foo

 

输出将是$moon = gibbous

-- 这里 $moon 作为字面输出,因为他并没有定义。而gibbous 将在$foo 的位置输出。

 

我们也可以转义VTL 指令,这将在指令一节祥述。

 

2.       Case Substitution

现在你大致了解了引用,可以在模板中使用它们了。Velocity 采用了很多JAVA原理的优点,模板设计人员会发现非常容易使用。例如:

$foo

 

$foo.getBar()

## is the same as

$foo.Bar

 

$data.getUser("jon")

## is the same as

$data.User("jon")

 

$data.getRequest().getServerName()

## is the same as

$data.Request.ServerName

## is the same as

${data.Request.ServerName}

这个例子显示了引用的一些其他用法。Velocity 借鉴了Java的自省和组件bean特征,来解决引用名在上下文中作为对象和对象方法的问题。可以在你的模板的任何地方插入引用和求值。

Velocity, 建模在Sun Microsystems定义的BEAN规范之上,是大小写敏感的;开发者努力捕捉和纠正可能出现的用户错误。当方法getFoo() 在模板中通过$bar.foo引用时,Velocity 首先尝试$getfoo。如果失败,他会再尝试 $getFoo。类似地,当一个模板引用到 $bar.Foo, Velocity 将尝试 $getFoo() 先,然后尝试 getfoo()。

注意: 模板中引用示例变量的问题仍然没有解决。 只有引用等价于JavaBean的 getter/setter 方法解决了。(比如 $foo.Name 解决了到类 Foo的 getName() 示例方法的引用,但不能引用Foo的一个公共实例变量Name)。

3.       指令

因为指令(使用脚本来有效操控JAVA代码的输出)允许页面设计员真正专注于咱点的外观和内容设计,引用允许模板设计员为Web页面产生动态内容。

 

3.1.     #set

 #set 指令用来为引用设置相应的值。值可以被值派给变量引用或者是属性引用,而且赋值要在括号里括起来。

#set( $primate = "monkey" )

#set( $customer.Behavior = $primate )

赋值的左边必须是一个变量应用或者是属性引用。右边可以是下面的类型之一:

变量引用

字面字符串

属性引用

方法引用

字面数字

数组列表

 

这些例子演示了上述的每种类型:

#set( $monkey = $bill ) ## variable reference

#set( $monkey.Friend = "monica" ) ## string literal

#set( $monkey.Blame = $whitehouse.Leak ) ## property reference

#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference

#set( $monkey.Number = 123 ) ##number literal

#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList

注意:最后一个例子中,在方括号[..] 中定义的项目可以被ArrayList 类定义的方法访问。 比如,你可以使用$monkey.Say.get(0)访问上述的第一个元素。

右边也可以是一个简单的算术表达式:

#set( $value = $foo + 1 )

#set( $value = $bar - 1 )

#set( $value = $foo * $bar )

#set( $value = $foo / $bar )

如果右边是一个属性或方法引用,取值是NULL,他将不会赋值给左边。通过这种机制将一个存在的引用从上下文中删除是不可能的。这对Velocity的新手可能会混淆。例如:

#set( $result = $query.criteria("name") )

The result of the first query is $result

 

#set( $result = $query.criteria("address") )

The result of the second query is $result

 

 

如果, $query.criteria("name") 放回字符串"bill",而$query.criteria("address") 返回 null,上述VTL 将解释为:

The result of the first query is bill

 

The result of the second query is bill

这往往会给那些想构建#foreach循环来试图通过属性和方法引用来设置一个引用的新手带来困惑,下面马上通过#if指令测试一下。例如:

#set( $criteria = ["name", "address"] )

 

#foreach( $criterion in $criteria )

 

    #set( $result = $query.criteria($criterion) )

 

    #if( $result )

        Query was successful

    #end

 

#end

在上面的例子中,依靠$result 的去值来决定查询是否成功恐怕不是英明的做法。 当$result 被#set设置后(添加到上下文中),他就不能再被设值为null (从上下文中删除)。

 

我们对此的解决方法是预设$result 为 false。 然后如果 $query.criteria() 调用失败,你就可以检查之。

 

#set( $criteria = ["name", "address"] )

 

#foreach( $criterion in $criteria )

 

    #set( $result = false )

    #set( $result = $query.criteria($criterion) )

 

    #if( $result )

        Query was successful

    #end

 

#end

不象其他Velocity 指令, #set 指令没有#end 语句。

3.2.       字面字符串

当使用#set 指令时,括在双引号中的字面字符串将解析和重新解释,如下所示:

#set( $directoryRoot = "www" )

#set( $templateName = "index.vm" )

#set( $template = "$directoryRoot/$templateName" )

$template

输出将会是:

www/index.vm

 

然而,当字面字符串括在单引号中时,他将不被解析:

#set( $foo = "bar" )

$foo

#set( $blargh = '$foo' )

$blargh

 

输出是:

Bar

  $foo

默认情况下,使用单引号来渲染未解析文本在Velocity是有效的。这种特征可以通过编辑velocity.properties 中的 stringliterals.interpolate=false来改变。

 

3.3.     条件 3.4.     If / ElseIf / Else

 Velocity中的#if 指令允许在页面生成时,在IF条件为真的情况下包含文本。例如:

#if( $foo )

   <strong>Velocity!</strong>

#end

 

变量 $foo 先求值,以决定是否为真。在这两种情况下为真: (i) $foo 是一个逻辑变量并具有真的值,或者 (ii) 值非空。要记住Velocity 上下文仅包括对象,所以当我们说“布尔”'boolean'时,他会被表示为“布尔类”(Boolean class)。 这对即使是返回布尔类型的方法也是真的—自省架构将返回一个具有相同逻辑值的布尔类。

如果求值为真时, #if 和 #end 语句之间的内容将输出。在这种情况下,如果 $foo 为真,输出将是"Velocity!"。相反,如果 $foo 具有一个null 值,或者逻辑假,语句求值为假,则没有输出。

一个 #elseif 或者 #else 项可以用在#if 语句中。请注意, Velocity 模板引擎将在第一个为真的表达式时停止。下面的例子中,假设$foo 具有值15 而 $bar 等于 6。

 

#if( $foo < 10 )

    <strong>Go North</strong>

#elseif( $foo == 10 )

    <strong>Go East</strong>

#elseif( $bar == 6 )

    <strong>Go South</strong>

#else

    <strong>Go West</strong>

#end

在这个例子中,$foo 大于10,所以前面两个比较失败。接下来比较$bar 和6,结果为真,所以输出为Go South。

请注意在现在, Velocity的数值比较约束为整型—其他类型都将求值为false。 仅有一个例外是等于'==',这时Velocity 要求等号两边的对象具有相同的类型。

3.5.     关系和逻辑操作符

Velocity 使用等式操作符来决定两个变量间的关系。这里是一个简单的例子演示如何使用等式操作符:

#set ($foo = "deoxyribonucleic acid")

#set ($bar = "ribonucleic acid")

 

#if ($foo == $bar)

  In this case it's clear they aren't equivalent. So...

#else

  They are not equivalent and this will be the output.

#end

Velocity 也具有逻辑AND, OR 和 NOT 操作符。更进一步的信息,请看VTL参考手册VTL Reference Guide 。下面是一些演示如何使用逻辑操作符的例子:

## logical AND

 

#if( $foo && $bar )

   <strong> This AND that</strong>

#end

 

例子中#if() 指令仅在$foo 和$bar 斗为真的时候才为真。如果$foo 为假,则表达式也为假;并且 $bar 将不被求值。如果 $foo 为真,Velocity 模板引擎将继续检查$bar;的值,如果 $bar 为真,则整个表达式为真。并且输出This AND that 。如果 $bar 为假,将没有输出因为整个表达式为假。

逻辑OR 的工作方式相同,唯一的例外是其中一个表达式要被求值,以便决定整个表达式是否为真。请看下面的例子:

 

## logical OR

 

#if( $foo || $bar )

    <strong>This OR That</strong>

#end

如果 $foo 为真,Velocity 模板引擎就不需要去察看$bar  的值,不管 $bar 是否为真,真个表达式都为真,因此输出This OR That 。如果 $foo 为假,$bar 就必须检查其值了。在这种情况下,如果$bar 也是为假,表达式将为假,没有任何输出。当然,如果$bar 为真,则真个表达式为真,输出This OR That。

对于逻辑NOT 操作符,只有一个操作数:

##logical NOT

 

#if( !$foo )

  <strong>NOT that</strong>

#end

 

这里,如果$foo 为真,!$foo 求值为假,没有输出。如果$foo 为假,!$foo 求值为真,输出NOT that 。请当心,不要和安静引用quiet reference $!foo 混淆它们是完全不同的。

本文地址:http://com.8s8s.com/it/it14716.htm