Velocity语法强化5之指令符号
2013-07-26 13:18
351 查看
模板设计者使用“引用“生成动态内容, 指令(directives) – 简单的说就是设计者在模板中操作java对象—让视图设计者全面控制输出内容的格式.
指令总是以 #开头后面紧跟具体的指令符. 就像引用一样(指令的一种),可以将指令理解为”表示这里是一个什么东东).如下例生成一个出错提示:
#if($a==1)true enough#elseno way!#end
这个例子中应使用括号将else分开.
#if($a==1)true enough#{else}no way!#end
#set( $primate = "monkey" )
#set( $customer.Behavior = $primate )
“左操作数被赋值“是引用操作的一个规则.=号右侧可能是以下类型之一:
· Variable reference变量引用
· String literal字符串
· Property reference 属性引用
· Method reference 命令引用
· Number literal 数字
· ArrayList 数组
· Map 映射
下面是对上述类型设置的示例:
#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
注意: 在ArrayList类型引用的例子中,其原素定义在数组 [..]中, 因此,你可以使表 $monkey.Say.get(0)访问第一个元素.
类似的,引用Map 的例子中, 原素定义在 { } 中,其键和值间以:隔成一对,使用 $monkey.Map.get("bannana") 在上例中将返回 'good', ( $monkey.Map.banana也会有同样效果).
下面是一般的计算表达式:
#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )
但注意:如果右边的操作数是一个属性或命令的引用而返回null,那么赋值将不会成功,且在随后的VTL中也不能再取出使用. 如下例:
#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, 上面的TVL输出结果将是:
The result of the first query is bill
The result of the second query is bill
这对与初学者的理解有些麻烦,比如在 #foreach loops中, 你使用 #set 给一个属性或命令赋值时,如下例示:
#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( $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.
另外, 指令 #literal 元素可以用来输出字面意思,如下示.
#literal()
#foreach ($woogie in $boogie)
nothing will happen to $woogie
#end
#end
会输出::
#foreach ($woogie in $boogie)
nothing will happen to $woogie
#end
#if 指令用来根据条件在页面中输出内容, 如下简单的例子:
#if( $foo )
<strong>Velocity!</strong>
#end
根据变量 $foo计算后是否为true决定输出, 这会有两种情况: (i) $foo 的是值是一个boolean (true/false)型并有一个true value, 或 (ii) 它是一个非null值. 要记者,Velocity context 中只能包含Objects, 因此当我们讲 'boolean'时, 它就是一个Boolean (the class).
在 #if 和 #end 的内容是否会输出,由$foo是否为true决定. 这里,如果 $foo is true, 输出将是: "Velocity!". 如果$foo 为null或false,将不会有任何输出.
#elseif 或 #else 可以和#if组合使用. 如果第一个表达式为true,将会不计算以后的流程,如下例假设t $foo 是15 and $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
输出将会是
Go South.
2.Relational and Logical Operators(关系和逻辑运算)
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
注意:== 计算与java中的 == 计算有些不同:不能用来测试对象是否相等(指向同一块内存). Velocity中是否相等仅直接的用来比较numbers, strings的值, or objects的toString()结果是否相等. 如果是不同的对象,会调用它们的toString()命令结果来比较.
Velocity也使用AND, OR and NOT 执行逻辑运算.详细说明请参看《VTL参考中文版》,如下是一些简单示例:
## logical AND
#if( $foo && $bar )
<strong> This AND that</strong>
#end
仅当 $foo $bar 和都为true时,#if()才会输出中间内容.
OR 运算例子
## logical OR
#if( $foo || $bar )
<strong>This OR That</strong>
#end
$foo或$bar只要有一个为true就可以输出。
NOT运算则只有一个操作参数或表达式 :
##logical NOT
#if( !$foo )
<strong>NOT that</strong>
#end
考虑下,下面的例子有几种输出结果?.
#if( $foo == $bar)it's true!#{else}it's not!#end</li>
#foreach 用来创建循环. For example:
<ul>
#foreach( $product in $allProducts )
<li>$product</li>
#end
</ul>
#foreach 会生成包含$products中对象的一个列表. 每一次循环都会将列表中的一个对象赋与变量$product .
$allProducts 或以是一个Vector, a Hashtable or an Array类型的容器. 指定给变量 $product 是一个引用到其中一个java对象的引用. For example, if $product 确实是一个java代码中的Product class i,它可以这样的方法访问$product.Name method (ie: $Product.getName()).
我们假设 $allProducts 是一个Hashtable.看看取出其中的东东多么简单:
<ul>
#foreach( $key in $allProducts.keySet() )
<li>Key: $key -> Value: $allProducts.get($key)</li>
#end
</ul>
通过引用变量$velocityCount可以访问到Velocity提供的计数器:
<table>
#foreach( $customer in $customerList )
<tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end
</table>
$velocityCount默认的计数器引用,你可以在配置 velocity.properties中改成你喜欢的:
# Default name of the loop counter
# variable reference.
directive.foreach.counter.name = velocityCount
# Default starting value of the loop
# counter variable reference.
directive.foreach.counter.initial.value = 1
当然,你还可以设置其它参数,具体见《Velocity Java开发指南中文版》中讲解.
# The maximum allowed number of loops.
directive.foreach.maxloops = -1
#include( "one.txt" )
如果需要引入多个文件,可以像下面这样.
#include( "one.gif","two.txt","three.htm" )
当然,还可用一个变量名来代替文件名引入.
#include( "greetings.txt", $seasonalstock )
#parse( "me.vm" )
与 #include 指令不同, #parse 可以从引入的模板中得到变量引用.但#parse指令只能接受一个参数.
VTL templates 被#parse 的模板中还可以再包含#parse声明,默认的深度为10,这是由配置参数directive.parse.max.depth在文件velocity.properties中决定的,你可以修改它以适合项目要求
#stop
8.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的输出,最终的输出如下:
<table>
<tr><td bgcolor="blue">Superior</td></tr>
<tr><td bgcolor="blue">Michigan</td></tr>
<tr><td bgcolor="blue">Huron</td></tr>
<tr><td bgcolor="blue">Erie</td></tr>
<tr><td bgcolor="blue">Ontario</td></tr>
</table>
宏一般被定义在模板中,那么站点上的其它模板中又如何调用呢?如能定义一个可以更大范围内共想的宏就太好了
如果将宏#tablerows($color $list) 定义到一个模板库中(Velocimacros template library), 其它模板就都可以访问它了.
Velocimacro Arguments(宏的参数)
Velocimacros可以从TVL中接受以下参数 :
· 引用类型 : 所有以'$'开头的
· String literal : something like "$foo" or 'hello'
· Number literal : 1, 2 etc
· IntegerRange : [ 1..2] or [$foo .. $bar]
· ObjectArray : [ "a", "b", "c"]
· boolean value true
· boolean value false
当传一个引用参数给宏时, 引用是通过名字传入的('pass by name').
#macro( callme $a )
$a $a $a
#end
#callme( $foo.bar() )
上例中命令 bar() 被调用了3 times.
最后要说的是,这个特性有些难以学习,但当你精心组织规划你的宏库时, 消除在VTL中重复功能的脚本时 –你可以像使用一个对象或组件一样使用宏, 比如一个宏对象生成多个表格的重复色彩.
如果你想利用这个特性,你只需要像下面那样简单的编码传一个值给它来调用 :
#set( $myval = $foo.bar() )
#callme( $myval )
Velocimacro Properties(宏的属性)
配置文件 velocity.properties 中有多行相关配置,具体请见《Velocity Java开发指南中文版》.
velocimacro.library –用来指定全局的宏库,多个可以,号分开.
velocimacro.permissions.allow.inline – 默认为true,可以让宏定义在一个正规的模板文件中.
velocimacro.permissions.allow.inline.to.replace.global – 用来指定模板内定义的宏的功能是否要以替换全局库,默认为false.
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中查找元素的过程.
指令总是以 #开头后面紧跟具体的指令符. 就像引用一样(指令的一种),可以将指令理解为”表示这里是一个什么东东).如下例生成一个出错提示:
#if($a==1)true enough#elseno way!#end
这个例子中应使用括号将else分开.
#if($a==1)true enough#{else}no way!#end
1.#set指令
#set 用来给一个引用赋值.值可以被赋给变量引用或属性引用, 但要将它们放入括号中,如下示:#set( $primate = "monkey" )
#set( $customer.Behavior = $primate )
“左操作数被赋值“是引用操作的一个规则.=号右侧可能是以下类型之一:
· Variable reference变量引用
· String literal字符串
· Property reference 属性引用
· Method reference 命令引用
· Number literal 数字
· ArrayList 数组
· Map 映射
下面是对上述类型设置的示例:
#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
注意: 在ArrayList类型引用的例子中,其原素定义在数组 [..]中, 因此,你可以使表 $monkey.Say.get(0)访问第一个元素.
类似的,引用Map 的例子中, 原素定义在 { } 中,其键和值间以:隔成一对,使用 $monkey.Map.get("bannana") 在上例中将返回 'good', ( $monkey.Map.banana也会有同样效果).
下面是一般的计算表达式:
#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )
但注意:如果右边的操作数是一个属性或命令的引用而返回null,那么赋值将不会成功,且在随后的VTL中也不能再取出使用. 如下例:
#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, 上面的TVL输出结果将是:
The result of the first query is bill
The result of the second query is bill
这对与初学者的理解有些麻烦,比如在 #foreach loops中, 你使用 #set 给一个属性或命令赋值时,如下例示:
#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 来声明结尾.
2.Literals (语义解析)
使用#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.
另外, 指令 #literal 元素可以用来输出字面意思,如下示.
#literal()
#foreach ($woogie in $boogie)
nothing will happen to $woogie
#end
#end
会输出::
#foreach ($woogie in $boogie)
nothing will happen to $woogie
#end
3.Conditionals(条件判断)
1.If / ElseIf / Else#if 指令用来根据条件在页面中输出内容, 如下简单的例子:
#if( $foo )
<strong>Velocity!</strong>
#end
根据变量 $foo计算后是否为true决定输出, 这会有两种情况: (i) $foo 的是值是一个boolean (true/false)型并有一个true value, 或 (ii) 它是一个非null值. 要记者,Velocity context 中只能包含Objects, 因此当我们讲 'boolean'时, 它就是一个Boolean (the class).
在 #if 和 #end 的内容是否会输出,由$foo是否为true决定. 这里,如果 $foo is true, 输出将是: "Velocity!". 如果$foo 为null或false,将不会有任何输出.
#elseif 或 #else 可以和#if组合使用. 如果第一个表达式为true,将会不计算以后的流程,如下例假设t $foo 是15 and $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
输出将会是
Go South.
2.Relational and Logical Operators(关系和逻辑运算)
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
注意:== 计算与java中的 == 计算有些不同:不能用来测试对象是否相等(指向同一块内存). Velocity中是否相等仅直接的用来比较numbers, strings的值, or objects的toString()结果是否相等. 如果是不同的对象,会调用它们的toString()命令结果来比较.
Velocity也使用AND, OR and NOT 执行逻辑运算.详细说明请参看《VTL参考中文版》,如下是一些简单示例:
## logical AND
#if( $foo && $bar )
<strong> This AND that</strong>
#end
仅当 $foo $bar 和都为true时,#if()才会输出中间内容.
OR 运算例子
## logical OR
#if( $foo || $bar )
<strong>This OR That</strong>
#end
$foo或$bar只要有一个为true就可以输出。
NOT运算则只有一个操作参数或表达式 :
##logical NOT
#if( !$foo )
<strong>NOT that</strong>
#end
考虑下,下面的例子有几种输出结果?.
#if( $foo == $bar)it's true!#{else}it's not!#end</li>
4.Loops(循环)
Foreach Loop#foreach 用来创建循环. For example:
<ul>
#foreach( $product in $allProducts )
<li>$product</li>
#end
</ul>
#foreach 会生成包含$products中对象的一个列表. 每一次循环都会将列表中的一个对象赋与变量$product .
$allProducts 或以是一个Vector, a Hashtable or an Array类型的容器. 指定给变量 $product 是一个引用到其中一个java对象的引用. For example, if $product 确实是一个java代码中的Product class i,它可以这样的方法访问$product.Name method (ie: $Product.getName()).
我们假设 $allProducts 是一个Hashtable.看看取出其中的东东多么简单:
<ul>
#foreach( $key in $allProducts.keySet() )
<li>Key: $key -> Value: $allProducts.get($key)</li>
#end
</ul>
通过引用变量$velocityCount可以访问到Velocity提供的计数器:
<table>
#foreach( $customer in $customerList )
<tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end
</table>
$velocityCount默认的计数器引用,你可以在配置 velocity.properties中改成你喜欢的:
# Default name of the loop counter
# variable reference.
directive.foreach.counter.name = velocityCount
# Default starting value of the loop
# counter variable reference.
directive.foreach.counter.initial.value = 1
当然,你还可以设置其它参数,具体见《Velocity Java开发指南中文版》中讲解.
# The maximum allowed number of loops.
directive.foreach.maxloops = -1
5.Include(引入)
#include 脚本元素让模板设计者可以在模板中引入一个本地文件, 这个被引入的文件将不会经过Velocity的解析. 安全起见,可以引入的文件只是配置参数TEMPLATE_ROOT所定义目录下的,默认为当前目录下.#include( "one.txt" )
如果需要引入多个文件,可以像下面这样.
#include( "one.gif","two.txt","three.htm" )
当然,还可用一个变量名来代替文件名引入.
#include( "greetings.txt", $seasonalstock )
6.Parse(解析模板)
#parse 元素指示可以引入一个包含TVL的本地文件,这个文件将被Veloict engine解析输出。.#parse( "me.vm" )
与 #include 指令不同, #parse 可以从引入的模板中得到变量引用.但#parse指令只能接受一个参数.
VTL templates 被#parse 的模板中还可以再包含#parse声明,默认的深度为10,这是由配置参数directive.parse.max.depth在文件velocity.properties中决定的,你可以修改它以适合项目要求
7.Stop
#stop 指令用来指示在模板的某处,engine停止解析,这一般用来调用。用法很简单.#stop
8.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的输出,最终的输出如下:
<table>
<tr><td bgcolor="blue">Superior</td></tr>
<tr><td bgcolor="blue">Michigan</td></tr>
<tr><td bgcolor="blue">Huron</td></tr>
<tr><td bgcolor="blue">Erie</td></tr>
<tr><td bgcolor="blue">Ontario</td></tr>
</table>
宏一般被定义在模板中,那么站点上的其它模板中又如何调用呢?如能定义一个可以更大范围内共想的宏就太好了
如果将宏#tablerows($color $list) 定义到一个模板库中(Velocimacros template library), 其它模板就都可以访问它了.
Velocimacro Arguments(宏的参数)
Velocimacros可以从TVL中接受以下参数 :
· 引用类型 : 所有以'$'开头的
· String literal : something like "$foo" or 'hello'
· Number literal : 1, 2 etc
· IntegerRange : [ 1..2] or [$foo .. $bar]
· ObjectArray : [ "a", "b", "c"]
· boolean value true
· boolean value false
当传一个引用参数给宏时, 引用是通过名字传入的('pass by name').
#macro( callme $a )
$a $a $a
#end
#callme( $foo.bar() )
上例中命令 bar() 被调用了3 times.
最后要说的是,这个特性有些难以学习,但当你精心组织规划你的宏库时, 消除在VTL中重复功能的脚本时 –你可以像使用一个对象或组件一样使用宏, 比如一个宏对象生成多个表格的重复色彩.
如果你想利用这个特性,你只需要像下面那样简单的编码传一个值给它来调用 :
#set( $myval = $foo.bar() )
#callme( $myval )
Velocimacro Properties(宏的属性)
配置文件 velocity.properties 中有多行相关配置,具体请见《Velocity Java开发指南中文版》.
velocimacro.library –用来指定全局的宏库,多个可以,号分开.
velocimacro.permissions.allow.inline – 默认为true,可以让宏定义在一个正规的模板文件中.
velocimacro.permissions.allow.inline.to.replace.global – 用来指定模板内定义的宏的功能是否要以替换全局库,默认为false.
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中查找元素的过程.
相关文章推荐
- Velocity语法强化1之#与$
- Velocity语法强化2之注释#与一个例子
- Velocity语法强化3之References(引用)
- Velocity语法强化4之语义问题
- NVelocity系列 → NVelocity 语法及指令
- Velocity语法强化56之强大的宏
- Velocity语法强化7之字符串
- angular指令中scope三个符号的说明
- nginx的基本配置--配置文件语法和配置指令
- Velocity 语法
- Monorail NVelocity语法整理
- [置顶] Freemaker FTL指令常用标签及语法
- velocity逃逸符号
- Velocity脚本基本语法简介
- ARM汇编中^、!、cxsf符号和movs等指令使用
- Velocity(10)——指令的转义
- 【语法回顾】:C++中的:模板类,友元函数,符号重载
- JSP语法(7)Page 指令
- velocity语法小结
- 编写自定义的 Velocity 指令