Velocity ⽂档(1)
Velocity 是什么?
Velocity 是⼀个基于java 的模板引擎(template engine )。它允许任何⼈仅仅简单的使⽤模板语⾔(template language )来引⽤由java 代码定义的对象。 当Velocity 应⽤于web 开发时,界⾯设计⼈员可以和java 程序开发⼈员同步开发⼀个遵循MVC 架构的web 站点,也就是说,页⾯设计⼈员可以只关注页⾯的显⽰效果,⽽由java 程序开发⼈员关注业务逻辑编码。Velocity 将java 代码从web 页⾯中分离出来,这样为web 站点的长期维护提供了便利,同时也为我们在JSP 和PHP 之外⼜提供了⼀种可选的⽅案。
Velocity 的能⼒远不⽌web 站点开发这个领域,例如,它可以从模板(template )产⽣SQL 和PostScript 、XML ,它也可以被当作⼀个独⽴⼯具来产⽣源代码和报告,或者作为其他系统的集成组件使⽤。Velocity 也可以为Turbine web 开发架构提供模板服务(template service )。Velocity+Turbine 提供⼀个模板服务的⽅式允许⼀个web 应⽤以⼀个真正的MVC 模型进⾏开发。
Velocity 能为我们做什么?
假设你是⼀家专门出售Mud 的在线商店的页⾯设计⼈员,让我们暂且称它为“在线MUD 商店”。你们的业
务很旺,客户下了各种类型和数量的mud 订单。他们都是通过输⼊⽤户名和密码后才登陆到你的⽹站,登陆后就允许他们查看订单并购买更多的mud 。现在,⼀种⾮常流⾏的mud 正在打折销售。另外有⼀些客户规律性的购买另外⼀种也在打折但是不是很流⾏的Bright Red Mud ,由于购买的⼈并不多所以它被安置在页⾯的边缘。所有⽤户的信息都是被跟踪并存放于数据库中的,所以某天有⼀个问题可能会冒出来:为什么不使⽤velocity 来使⽤户更好的浏览他们感兴趣的商品呢?
Velocity 使得web 页⾯的个性化⼯作⾮常容易。作为⼀个web site 的设计⼈员,你希望每个⽤户登陆时都拥有⾃⼰的页⾯。 你会见了⼀些公司内的软件⼯程师,你发现他们每个⼈都同意客户应该拥有具有个性化的信息。那让我们把软件⼯程师应该作的事情发在⼀边,看⼀看你应该作些什么吧。
你可能在页⾯内嵌套如下的VTL 声明:
Velocity Template Language(VTL)介绍
VTL 意味着提供最简单、最容易并且最整洁的⽅式合并页⾯动态内容。
VTL 使⽤引⽤(references )来在web site 内嵌套动态内容。⼀个变量就是⼀种类型的reference 。变量是某种类型的refreence 。它可以指向java 代码中定义的对象,或者在当前页⾯内使⽤VTL statement 定义的变量。下⾯是⼀个VTL statement 的例⼦,它可以被嵌套到HTML 代码中:
和所有的VTL statement ⼀样,这个statement 以#字符开始并且包含⼀个directive :set 。当⼀个在线⽤户请求你的页⾯时,Velocity Templating Engine 将查询整个页⾯以便发现所有#字符,然后确定哪些是VTL statement ,哪些不需要VTL 作任何事情。 #字符后紧跟⼀个directive :set 时,这个set directive 使⽤⼀个表达式 (使⽤⼀对圆括号`(` , `)` 封闭) 分配⼀个值给变量$a 。变量被列在左边,⽽它的值被列在右边,最后他们之间使⽤=号分割。
⼀旦某个变量被分配了⼀个值,那么你就可以在HTML ⽂件的任何地⽅引⽤它。在下⾯的例⼦中,⼀个值被分配给$foo 变量,并在其后被引⽤。 上⾯的实现结果是在页⾯上打印“Hello Velocity World !”
为了使包含VTL directives 的statement 更具有可读性,我们建议在新⾏开始每个VTL statement ,尽管你不是必须这么作。Set directive 将在后⾯详细描述。注释
单⾏注释:
多⾏注释:
01<html >02 <body >03 Hello $customer.Name!04 <table >05 #foreach( $mud in $nudsOnSpecial )06 #if ( $customer.hasPurchased( $mud ) )07 <tr >08 <td >$Promo( $mud )</td >09 </tr >10 #end 11 #end 12 </table >13 </body >14</html >
1#set ( $a = “Velocity” )
记住以下的规则: 使⽤$字符开始的references ⽤于得到什么;使⽤#字符开始的directives ⽤于作些什么。
1<html >2 <body >3 #set ( $foo = “Velocity” )4 Hello $foo World!5 </body >6</html >
1## This is a single line comment.
1 #*
2 Thus begins a multi-line comment. Online visitors won’t
3 see this text because the Velocity Templating Engine will 4ignore it.5 *#
⽂档格式:
Referencesjsp帮助文档
在VTL 中有三种类型的references :变量(variables)、属性(properties)、⽅法(methods)。
作为⼀个使⽤VTL 的页⾯设计者,你和你的⼯程师必须就references 的名称达成共识,以便你可以在你的template 中使⽤它们。
Everything coming to and from a reference 被作为⼀个String 对象处理。如果有⼀个对象$foo 是⼀个Integer 对象,那么Velocity 将调⽤它的toString()⽅法将这个对象转型为String 类型。
变量
格式要求同java 。
属性
例⼦:
其中$customer.Address 有两种含义。它既可以表⽰查hashtable 对象customer 中以Address 为关键字的值, 也可以表⽰调⽤customer 对象的getAddress()⽅法。当你的页⾯被请求时,Velocity 将确定以上两种⽅式选⽤那种,然后返回适当的值。
⽅法
⼀个⽅法就是被定义在java 中的⼀段代码,并且它有完成某些有⽤⼯作的能⼒,例如⼀个执⾏计算和判断条件是否成⽴、满⾜等。⽅法是⼀个由$开始并跟随VTL 标识符组成的References ,⼀般还包括⼀个VTL ⽅法体。例如:
前两个例⼦$Address()和$Total()看起来挺想上⾯的属性$customer.Address 和 $purchase.Total 。如果你觉得他们之间有某种联系的话,那你是正确的;因为VTL 属性可以作为VTL ⽅法的缩写。$customer.Address 属性和使⽤$Address()⽅法具有相同的效果。如果可能的话使⽤属性的⽅式是⽐较合理的。属性和⽅法的不同点在于你能够给⼀个⽅法指定⼀个参数列表。
正式reference 标记
reference 的正是格式如下:
但⾮正式格式更常见,但是有时还是使⽤正式格式⽐较好。例如:你希望通过⼀个变量$vice 来动态的组织⼀个字符串:
本来⽤意是是引⽤变量$vice ,现在却变成了$vicemaniac ,这样Veloctiy 就不知道您到底要什么了。所以在这种情况下应该使⽤正式格式书写:
现在Velocity 知道你希望引⽤的变量是$vice ⽽不是$vicemaniac , 模板被渲染后的结果为:
Quiet reference notation
关于空值(null)的处理
当⼀个变量没有被定义或为空值(null) , velocity 模板会将该变量名连同美元符号⼀起输出。考虑如下的html ⽚段:
当页⾯的form 被初始加载时,变量$email 还没有值,这时你肯定是希望它能够显⽰⼀个空字符串("")来代替$email 这样的字符串,那么就需要使⽤quiet reference notation ,即$!标记
1#**2 This is a VTL comment block and 3 may be used to store such information 4as the document author and versioning 5 information:6 @version 57 @author 8 *#
1$customer.Address 2$purchase.Total
Address()Total()3$page.setTitle( “My Home Page” )4$person.setAttributes( [“Strange”, “Weird”, “Excited”] )
Velocity 利⽤了很多java 规范以⽅便了设计⼈员的使⽤。例如
$Bar() 等同于 $foo.Bar 等同于 ${foo.Bar}
$User(“jon”) 等同于 $data.User(“jon”) 等同于 ${data.User("join")}
$Request().getServerName() 等同于 $data.Request.ServerName 等同于 ${data.Request.ServerName}
需要明确的是VTL 中不会将reference 解释为对象的实例变量。例如:$foo.Name 将被解释为Foo 对象的getName ()⽅法(假如$foo 所引⽤的对象不是Hashtale 对象),⽽不是Foo
对象的Name 实例变量。
1${mudSlinger} ##变量2${customer.Address} ##属性3${Total()} ##⽅法
1Jack is a $vicemaniac.
1Jack is a ${vice}maniac
1<input type=”text” name=”email” value=”$email” />
当然 使⽤正式的quiet 格式会更好:
关于特殊字符的处理
Velocity 使⽤特殊字符$和#来帮助它⼯作,所以如果要在template ⾥使⽤这些特殊字符要格外⼩⼼。
在VTL 中, 像$2.5这样的标识符不会被认为是⼀个reference ,因为VTL 中的reference 总是以⼀个⼤写或者⼩写的字母开始.
VTL 中使⽤“\”作为转义符。
例如:
将被渲染为:
foo
$email
\foo
\\$email
如果email 变量没有被定义则
将被渲染为:
$email
\$email
\\$email
\\\$email
指令(Directives )
reference 允许设计者使⽤动态的内容,⽽directive 使得你可以控制显⽰逻辑,从⽽达到期望的显⽰效果。
#set 指令
#set directive 被⽤于设置⼀个reference 的值。例如:
赋值左侧的(LHS )必须是⼀个变量或者属性reference 。右侧(RHS )可以是以下类型中⼀种:
变量引⽤(variable reference )
字符串字⾯值(String literal )
属性引⽤(property reference)
⽅法调⽤(method reference)
数字字⾯值( number literal)
数组列表(Array List)
下⾯是应⽤各种类型的RHS 的例⼦:
注意:最后⼀个例⼦的取值⽅法为:$(0)
RHS 也可以是⼀个简单的算术表达式:
如果你的RHS 是⼀个null ,VTL 的处理将⽐较特殊:它将指向⼀个已经存在的reference ,这对初学者来讲可能是⽐较费解的。例如:
如果$iteria(“name”)返回⼀个“bill”,⽽$iteria(“address”)返回的是null ,则显⽰的结果如下:
The result of the first query is bill
The result of the first query is bill
1<input type=”text” name=”email” value=”$!email”/>
1<input type=”text” name=”email” value=”$!{email}”/>
1#set( $email = “foo” )2$email 3\$email 4\\$email 5\\\$email
1$email 2\$email 3\\$email 4\\\$email
1#set ( $primate = “monkey” )2#set ( $customer.Behavior = $primate )
1#set ( $monkey = $bill ) ## 变量引⽤(variable reference )2#set ( $monkey.Friend = “monica” ) ##字符串字⾯值(String literal )3#set ( $monkey.Blame = $whitehouse.Leak )## 属性引⽤(property reference)4#set ( $monkey.Plan = $spindoctor.weave($web) )##⽅法调⽤(method reference)5#set ( $monkey.Number = 123 ) ## 数字字⾯值( number literal)6#set ( $monkey.Say = [“Not”, $my, “fault”] ) ##数组列表(Array List)
1#set ( $value = $foo + 1 )2#set ( $value = $bar -1 )3#set ( $value = $foo * $bar )4#set ( $value = $foo / $bar )
1#set ( $resut = $iteria(“name”) )2The result of the first query is $result 3#set ( $resut = $iteria(“address”) )4The result of the second query is $result
再看⼀个例⼦:
打印的结果将显⽰两次查询结果都成功了。
为什么会出现这种现象呢?其实当某个变量被赋值后,它就被保存到Velocity 的context(added to the context),并且buhui 不能被设置回null (removed from the context )。
为了解决以上问题我们可以通过预先定义的⽅式:
关于 字符串字⾯值(String Literals )
当你使⽤#set 指令时,如果把字符串字⾯值(String literal)封闭在⼀对双引号内, ⽐如
则渲染的结果为
www/index.vm
但是,当字符串字⾯值(String Literal )被封装在单引号内时,它将不被解析:
结果:
bar
$foo
这个特性可以通过修改velocity.properties ⽂件的属性设置
stringliterals.interpolate = false 来改变上⾯的特性失效。1#set( $criteria = ["name", "address"] )2#foreach( $criterion in $criteria )3 #set( $result = $iteria($criterion) )4 #if( $result )5 Query was successful 6 #end 7#end
1#set( $criteria = [“name”, “address”] )2#foreach( $criterion in $criteria )3 #set( $result = false )4 #set( $result = $iteria( $criterion ) )5 #if( $result )6 Query was successful 7 #end 8#end
1#set ( $directoryRoot = “www” )2#set ( $templateName = “index.vm” )3#set ( $template = “$directoryRoot/$tempateName” )4$template
1#set ( $foo = “bar” )2$foo 3
#set ( $blargh = ‘$foo’ )4$blargh
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论