Velocity Template Language: The unknown story

例示velocity模板语言中的一些陷阱


objects, strings, quotes

#set ($var = $list) $var.class, $var  
## java.util.List, list.toString()

#set ($var = ‘$list’) $var.class, $var  
## java.lang.String, "$list" 

#set ($var = "$list") $var.class, $var  
## java.lang.String, list.toString()    

———————————


public field not treated as property

$publicFieldBean.publicField   
##won’t work; velocity doesn’t recognize public fields as properties

———————————


maps are also supported

$map.firstKey, $map["firstKey"] 
##both equivelent to map.get("firstKey");

#foreach ($e in $map)

the map.entry is $e 
##will only print the value, no key rende#006699

#end

———————————


it will fail to assign null to a variable

#set ($o = $bean)

#set ($o = $nonExistingObject)

$o, $o.class  
## still the bean, not null

#set ($o = $!nonExistingObject)

$o, $o.class  
## still the bean, not empty string

#set ($o = "$!nonExistingObject")

$o, $o.class, $o.length()  
## now it’s an empty string

———————————

   
investigating bool

b1: #if(true) Go, true! #end  
##will print something

b2: #if(false) Go, false! #end  
##will print nothing

b3: #if("true") Go, "true"! #end    
##  will print nothing. 

b4: #if("false") Go, "false"! #end  
##  will print nothing. You can see "#if" doens’t take string literals

#set($theBool = false)

b5: #if($theBool) Go, "$theBool" #end 
## will print nothing

b6: #if("$theBool") Go, "the bool" #end 
##will print nothing since "#if" doens’t take string literals

#set($theBool = "false")

b7: #if($theBool) Go, "$theBool" #end 
## will print something since $theBool is not null

b8: #if("abc" == "abc") abc #end 
## For string comparison, "==" in VTL is equivlatent to .equals() in java

b9: #if($fakeObject) faked! #end 
## wil print nothing since $fakeObject doesn’t exist

b10: #if($!fakeObject) faked! #end  
## still prints nothing

b11: #if("$!fakeObject") faked! #end  
## still prints nothing

———————————


variable scope: variables defined in loops

#foreach ($b in $beans)

#set($bi = $foreach.count)

#end

   $!b   
##will print nothing

   $bi  
##will print the last index; you can see variables defined by "#set" have global socpes

———————————


variable scope: variables defined inside \#if statements

#if (true)

#set($ifv = "definedInsideIf")

#end   

   $ifv  
##will print something

———————————


variable scope: variables defined inside macros

#macro(inMacro)

#set($definedInsideMacro = "definedInsideMacro")

#end   

$!definedInsideMacro  
## will print nothing

#inMacro       

$definedInsideMacro  
## will print something

———————————


variable scope: reference global variables from macros

    #macro(printGlobal)

hello print global: $bean.firstProperty, $bean.lastProperty

#end

#printGlobal 
## will print something.

    #macro(printGlobalWithParam $bean)

hello print global with param: $bean.firstProperty, $bean.lastProperty

#end

#printGlobalWithParam  
## will print $bean’s properties

    #printGlobalWithParam ($beans[2]) 
##now it will print beans[2]’s properties

    ———————————


macro’s pass-by: neither pass-by-ref or pass-by-value, but pass-by-name

#macro(doIt $a)

$a $a

#end

#set($bb = $beans[1])

#doIt ($bb.setFirstProperty("${bb.firstProperty} & postfix ") )

$bb.firstProperty 
## will print "… & postfix & postfix" . The macro carries out "$bb.setFirstProperty("${bb.firstProperty} & postfix ")" for twice

———————————


does "=" mean reference assignment or value copy?

#set($bb = $beans[1])

$bb.setFirstProperty("newValue")

$bb.firstProperty

$beans[1].firstProperty   
##will print "newValue"

    ———————————


\#define dosen’t take arguments

#set($b3 = $beans[3])

#define ($printBean)

   hello $b3.firstProperty, hello $b3.lastProperty

#end

$printBean    
##print properties of $b3

$printBean($beans[1])  
## will not work

    ———————————


null value or undefined reference in non-strict reference mode

$emptyBean.firstProperty, $!emptyBean.firstProperty

$emptyBean.undefinedProperty, $!emptyBean.undefinedProperty

$emptyBean.firstProperty.length(), $!emptyBean.firstProperty.length()

    ———————————


notation: formal or informal ?

The size is $sizecm
##won’t work

    The size is ${size}cm 
##will work

    The size is ${size}#if(1==2)km#{else}cm#end  
##even a directive can be put as a formal notation

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.