1 | import java.io.StringWriter; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; public class HelloWorld { public static void main( String[] args ) throws Exception { /* first, get and initialize an engine */ VelocityEngine ve = new VelocityEngine(); ve.init(); /* next, get the Template */ Template t = ve.getTemplate( "helloworld.vm" ); /* create a context and add data */ VelocityContext context = new VelocityContext(); context.put("name", "World"); /* now render the template into a StringWriter */ StringWriter writer = new StringWriter(); t.merge( context, writer ); /* show the World */ System.out.println( writer.toString() ); } } |
1 | Hello World! Welcome to Velocity! |
1 | $petList.size() Pets on Sale! We are proud to offer these fine pets at these amazing prices. This month only, choose from: #foreach( $pet in $petList ) $pet.name for only $pet.price #end Call Today! |
1 | /* create our list of maps */ ArrayList list = new ArrayList(); Map map = new HashMap(); map.put("name", "horse"); map.put("price", "00.00"); list.add( map ); map = new HashMap(); map.put("name", "dog"); map.put("price", "9.99"); list.add( map ); map = new HashMap(); map.put("name", "bear"); map.put("price", ".99"); list.add( map ); /* add that list to a VelocityContext */ VelocityContext context = new VelocityContext(); context.put("petList", list); |
1 | import java.io.StringWriter; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; public class PetStoreEmail { public static void main( String[] args ) throws Exception { /* first, get and initialize an engine */ VelocityEngine ve = new VelocityEngine(); ve.init(); /* organize our data */ ArrayList list = new ArrayList(); Map map = new HashMap(); map.put("name", "horse"); map.put("price", "00.00"); list.add( map ); map = new HashMap(); map.put("name", "dog"); map.put("price", "9.99"); list.add( map ); map = new HashMap(); map.put("name", "bear"); map.put("price", ".99"); list.add( map ); /* add that list to a VelocityContext */ VelocityContext context = new VelocityContext(); context.put("petList", list); /* get the Template */ Template t = ve.getTemplate( "petstoreemail.vm" ); /* now render the template into a Writer */ StringWriter writer = new StringWriter(); t.merge( context, writer ); /* use the output in your email body */ sendEmail( writer.toString() ); } } |
1 | 3 Pets on Sale! We are proud to offer these fine pets at these amazing prices. This month only, choose from: horse for only 00.00 dog for only 9.99 bear for only .99 Call Today! |
1 | #set() #if() #else #elseif() #end #foreach() #include() #parse() #macro() |
1 | #set( $startrow = 0) #set( $count = $current + 1 ) #set( $isReady = ( $isOn && $isOpen) ) #if( $value > 5 ) bigger #elseif( $value < 5 ) smaller #else just right #end #foreach( $item in $itemList ) My $item. #end |
The collection types #foreach() supports are:
Object[]
java.util.Collection
java.util.Map (iterates over the mapped values)
java.util.Iterator
java.util.Enumeration
The #include() and #parse() directives are similar -- they both take a template or static resource name as an argument, include that template or resource in-place, and then render it to the output stream. The difference is that #include() includes the specified resource's content without any processing, and #parse() treats the specified resource as a template, processing all directives and references against the current context.
You can use these two directives to dynamically construct output. For example, in Web applications you can set up a skeleton for your pages, such as a set of top-level templates that may employ different navigational layouts or color/design schemes, and then #parse() and/or #include() the dynamic and static content elements at runtime based on user and application state:
#parse( $header ) |
#parse( $body ) |
#parse( $footer ) |
提示:velocity中大小写敏感。
Velocity还特别提供了得到循环次数的方法,$velocityCount变量的名字是Velocity默认的名字。
Velocity中的宏我们可以理解为函数。
①宏的定义
#macro(宏的名称 $参数1 $参数2 …)
语句体(即函数体)
#end
②宏的调用
#宏的名称($参数1 $参数2 …)
说明:参数之间用空格隔开。
1 | #macro( select $name $displayname $choicelist ) <SELECT name=$name> <option value="">$displayname</option> #foreach( $choice in $choicelist ) <option value=$choice>$choice</option> #end </select> #end |
Then, anytime you need an HTML <select> widget, you could simply invoke the Velocimacro as a directive:
1 | Please choose: #select( "size" "--SIZE--" $sizelist ) |
VTL miscellany
I should mention a few other VTL features. VTL lets you create integers, string literals, Boolean values, arrays of objects, and arrays of sequential integers in the template:
#set( $myint = 5 )
#set( $mystring = 'Hello There')
#set( $mybool = true )
#set( $objarr = [ "a", $myint, $mystring, false ] )
#set( $intrangearr = [1..10] )
VTL also has an alternative string literal form, using double quotes (") that interpolates reference values (plus directives and Velocimacros):
#set( $foo = 'bar')
#set( $interp = "The value is '$foo'")
The resulting value of $interp is the string The value is 'bar'.
/n/n/n/n/n
#include和#parse的作用都是引入本地文件, 为了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目录下。
区别:
(1) 与#include不同的是,#parse只能指定单个对象。而#include可以有多个
如果您需要引入多个文件,可以用逗号分隔就行:
#include ("one.gif", "two.txt", "three.htm" )
在括号内可以是文件名,但是更多的时候是使用变量的:
#include ( “greetings.txt”, $seasonalstock )
(2) #include被引入文件的内容将不会通过模板引擎解析;
而#parse引入的文件内容Velocity将解析其中的velocity语法并移交给模板,意思就是说相当与把引入的文件copy到文件中。
#parse是可以递归调用的,例如:如果dofoo.vm包含如下行:
Count down.
#set ($count = 8)
#parse ("parsefoo.vm")
All done with dofoo.vm!
那么在parsefoo.vm模板中,你可以包含如下VTL:
$count
#set($count = $count - 1)
#if ( $count > 0 )
#parse( "parsefoo.vm" )
#else
All done with parsefoo.vm!
#end的显示结果为:
Count down.
8
7
6
5
4
3
2
1
0
All done with parsefoo.vm!
All done with dofoo.vm!
注意:在vm中使用#parse来嵌套另外一个vm时的变量共享问题。如:
->a.vm 里嵌套 b.vm;
->a.vm 里定义了变量 $param;
->b.vm 里可以直接使用$param,无任何限制。
但需要特别注意的是,如果b.vm里同时定义有变量$param,则b.vm里将使用b.vm里定义的值