NVelocity语法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
默认情况下,NVelocity解析是不分大小写的,当然可以通过设置runtime.strict.math=true,采用严格解析模式。
##指定用户名字
欢迎你: $!
<table>
###输出用户喜好的MuD
#foreach( $mud in $mudsOnSpecial )
#if ( $customer.hasPurchased($mud) )
<tr>
<td>
$flogger.getPromo( $mud )
</td>
</tr>
#end
#end
</table>
set指示符使用一个表达式(expression) (包含在一对括号里) –将一个值value (这里是Velocity)付给变量a,(变量名在左边,值在右边,用=组合起来).
以$开头的表示“引用”意思是取得一些东东.可引用变量,属性,方法属性可以引用到对象的命令. Velocity会使用合适的策略选择引用到的命令. 它会根据协定的命令命令格式查找. 无论属性引用的的名字是否大小写,Velocity都有固定的查找规则.如在$customer.address引用时,查找顺序是:
getaddress()
getAddress()
get("address")
isAddress()
对于VTL中大写的属性名Address引用,将是:
getAddress()
getaddress()
get("Address")
isAddress()
正规引用格式
${mudSlinger}
1.Jack is a $vicemaniac.
2.Jack is a ${vice}maniac.
这样,Velocity就知你要的是$vice, 而不是$vicemaniac变量,正规引用格式一般用于在模板中直接调整字符串内容.
Quiet Reference Notation(静态引用输出)
Velocity遇到一个不能处理的引用时,一般他会直接输出这个引用$email的写法,页面上会看到的是$email,如下例,我们可以在$后面加上一个!号,那么就会输出空白:.
<input type="text"name="email"value="$email"/>
<input type="text"name="email"value="$!email"/>
正式的写法是:.
<input type="text"name="email"value="$! {email}"/>
Getting literal( 语义问题)
velocity使用$,#字符来标志它的声明,但有时,HTML中因为某种其它意图,也会写出这样的字符
1.Currency(货币标志)
如美元 $2.50!这样的写法出现到模板中, VTL处理时是不会出错,会正确的输出$2.50!这个你想要的结果。
为什么呢?一个合法的VTL标示符是以一个字母开头的
如下示,如果没有#set( $email = "foo" )这一行且java代码中Context对象中没有放放email对象,将直接输出$email.
#set( $email = "foo" )
$email
如果email己定义了 (比如它的值是foo),而这里你却想输出$email. 这样一个字符串,就需要使用转义字符”\”.
## The following line defines $email in this template:
#set( $email = "foo" )
$email
\$email
\\$email
\\\$email
上面的模板在web页面上的输出将是:
foo
$email
\foo
\$email
但如果email并没有定义,我们这样写:.
$email
\$email
\\$email
\\\$email
输出就原封不动了:
$email
\$email
\\$email
\\\$email
注意:当己定义变量和未定义变量一起输出时,会输出字面意思,如下便,$moon是未定义的:
#set( $foo = "gibbous" )
$moon = $foo
输出到web页面中将是
$moon = gibbou
Case Substitution(可选的格式)
$foo.getBar()
## 等同于
$foo.Bar
$data.setUser("jon")
##等同于
#set( $er = "jon" )
$data.getRequest().getServerName()
##等同于
$data.Request.ServerName
## is the same as
${data.Request.ServerName}
指令:(Directives)则以#开头来表示,有点“做些什么动作”的意思. #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
#set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## Map
注意:如果右边的操作数是一个属性或命令的引用而返回null,那么赋值将不会成功,且在随后的VTL中也不能再取出使用
#set( $criteria = ["name", "address"] )
#foreach( $criterion in $criteria )
#set( $result = $query.criteria($criterion) ) #if( $result )
Query was successful
#end
#end
在上例中,就不能依赖if( $result )来决定查询是否成功. $result一但被
#set 为null (context会同样), 它将不能被赋其它值 (不能从 context中取出).
一个解决办法是,每次都将$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
注意:#set不需要使用#end来声明结尾.
使用#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 such that stringliterals.interpolate=false.
通过引用变量$velocityCount可以访问到Velocity提供的计数器:
<table>
#foreach( $customer in $customerList )
<tr><td>$velocityCount</td>
<td>$</td></tr>
#end
</table>
#include脚本元素让模板设计者可以在模板中引入一个本地文件, 这个被引入的文件将不会经过Velocity的解析. 安全起见,可以引放的文件只是是配置参数TEMPLATE_ROOT所定义目录下的,默认为当前目录下. #include( "one.txt" )
如果需要引入多个文件,可以像下面这样.
#include( "one.gif","two.txt","three.htm" )
当然,还可用一个变量名来代替文件名引入.
#include( "greetings.txt", $seasonalstock )
#parse元素指示可以引入一个包含TVL的本地文件,这个文件将被Veloict engine解析输出。
.
#parse( "me.vm" )
与#include指令不同, #parse可以从引入的模板中得到变量引用.但#parse指令只能接受一个参数.
VTL templates 被#parse的模板中还可以再包含#parse声明,默认的深度为10,这是由配置参数directive.parse.max.depth在文件velocity.properties中决定的,你可以修改它以适合项目要求
#stop指令用来指示在模板的某处,engine停止解析,这一般用来调用。
用法很简单.
Velocimacros(宏调用)
#macro指令让模板设计者可以将些重复、相关的的脚本版断定义为一个功能块.无论在什么情况下. 出于单一意图设计的 Velocimacro都会最大程序的减少模板编写中可以的出错,还是看个例子来理解一下Velocimacros的概念.
#macro( d )
<tr><td></td></tr>
#end
这样就定义了一个名为d的宏,它可以在其它的模板中像下面那样直接引用:
#d()
Velocimacro可以接收0到任意多的传入参数.如上个例是0个参数,但当它被调用时,也必须传入同样多的参数. 这里定义了一个有两个参数的宏. #macro( tablerows $color $somelist )
#foreach( $something in $somelist )
<tr><td bgcolor=$color>$something</td></tr>
#end
#end
然后,我们在页面中来使用:
#set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] ) #set( $color = "blue" )
<table>
#tablerows( $color $greatlakes )
</table>
注意变量$greatlakes取代了宏中变量$somelist的输出,最终的输出如下:
Superior
Michigan
Huron
Erie
Ontario
宏一般被定义在模板中,那么站点上的其它模板中又如何调用呢?如能定义一个可以更大范围内共想的宏就太好了
如果将宏#tablerows($color $list)定义到一个模板库中(Velocimacros
velocimacro.permissions.allow.inline.local.scope –模板中定义的宏的使用范围是否只是本模板可用.
velocimacro.context.localscope –如果为true,宏通过#set赋值时.宏中将保持一个,且不会由于context中的数据被修改而变化,同样,宏中的修改也不会改变context中的。
velocimacro.library.autoreload – 是否自动重新载入,用于调试环境,默认false,如为true,需要取掉chcheing:. file.resource.loader.cache = false ).
一些细节:
宏必须在模板中使用#macro()指令前定义.
尽量不要直接在模板中使用#parse() 包含 #macro() 指令.因为 #parse()动作在运行时执行,时会有一个在VM中查找元素的过程.
两种注释方式:
##
#* ……*#
Velocimacro Miscellany(关于宏的一些问题)
这是一些简短的问题总结,也许你先要有这样一个概念:. 'Velocimacro'就像一个‘VM’。
可否用一个指示符做为另外一个指示符运算的参数?
如 : #center( #bold("hello") )
No. 指示符不是有效的参数但你可以这样实现你想要的:
#set($stuff = "#bold('hello')" )
#center( $stuff )
或者:
#center( "#bold( 'hello' )" )
可否通过 #parse()来注册一个宏 ?
宏必须在模板使用前定义好.前面己有一个关于此问题的建议,#parse()是运行时执进的,JVM查找对象的顺序不一定会全按我们预计的执行。
String Concatenation(连结字符串)
很简单,看例子就是 :
#set( $size = "Big" )
#set( $name = "Ben" )
The clock is $size$name.
上面的输出将是
'The clock is BigBen'.
或者:
#set( $size = "Big" )
#set( $name = "Ben" )
#set($clock = "$size$name" )
The clock is $clock.
它们都是同样的输出,最后一个例子如下,:
#set( $size = "Big" )
#set( $name = "Ben" )
#set($clock = "${size}Tall$name" ) The clock is $clock.
输出将是
'The clock is BigTallBen'.
Layout应用:
首先Layout母板页
$childContent
然后在子页面里
#capturefor(title) Home Page #end
#capturefor(scripts)
function sayHello()
{
return alert("Hello");
}
#end
#capturefor(head)
#end
表格行奇偶样式变换
#foreach($test in $tests)
#even
<tr class="Test1">
#odd
<tr class="Test2">
#each
<td>$</td>
<tr>
#end
附:NVelocity常用语法指令
对变量的引用:$ [ ! ][ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ][ } ]。
在NVelocity中,对变量的引用都是以$开头加上变量名称。
当使用!时表示当此变量值为空时,显示空字符串。
比如当$article为空,那会显
示“$article“,而$!article会显示为“”。
{}为变量名称限定,有时候变量名称后会有字符串,这是就需要用到{}了。
比如$articleshow,想引用$article,这时只要修改为${article}就可以。
其实,NVelocity对整个模板解析后都会变成这种模式。
对属性的引用:$ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[a..z, A..Z ][ a..z, A-Z, 0..9, -, _ ]* [ } ] 。
例如$article.Title或者${article.Title}。
对方法的引用:$ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]*( [ optional parameter list... ] ) [ } ]。
例如:$article.GetListByTitle('nvelocity')或
${article.GetListByTitle('nvelocity')}。
其实对对象的属性值也可以用$article.get_Title()获得。
赋值指令#set:# [ { ] set [ } ] ( $ref = [ ", ' ]arg[ ", ' ] )。
例如:$article.Title='NVelocity',$$article.Categories=[1,2,3],当然右侧也可以使用复杂的表达式:
$article.Title=$otherArticle.Title.SubString(0,3),算术表达式:$article.Page=4/3等等。
属性赋值也可以用
$article.set_Title('NVelocity')。
条件指令#if:# [ { ] if [ } ] ( [condition] ) [output] [ # [ { ] elseif [ } ] ( [condition] ) [output] ]* [ # [ { ] else [ } ] [output] ] # [ { ] end [ } ] 。
条件可以是返回bool的复查表达式。
例如:#if($article.Total>1) $article.Title #else 没有数据 #end。
循环指令#foreach:# [ { ] foreach [ } ] ($refinarg)statement# [ { ] end [ } ]。
例如:#foreach($article in $articles) $article.Title #end。
引用静态资源指令#include:# [ { ] include [ } ] ( arg[ arg2 ... argn] )。
例如:#include('tmp.js'),会把tmp.js文件内容插入当前流。
当然可以使用表达式:#include($article.Url)。
引用并解析资源指令#parse:# [ { ] parse [ } ] ( arg )。
例如:#parse('tmp.js'),与#include不同是,假如tmp.js文件中有NVelocity的指令,变量会进行处理,并把结果插入到当前流。
停止指令#stop:# [ { ] stop [ } ] 。
当NVelocity解析到此指令时,会停止解析过程。
一般用户调试。
计算指令#evaluate:# [ { ] evaluate [ } ] ( arg )。
例如:#evaluate('$article.Title'),会在当前输出$article.Title。