《Velocity 模板使用指南》中文版

xiaoxiao2026-05-25  16

Velocity 模板使用指南》中文版 源文见 http://velocity.apache.org 声明: 转载请保留此页声明 ************************************************************************** 此文档为蓝杰实训学员拓展实训之用. 蓝杰实训不对译文中某些说法可能会对您的系统或开发造成损害负责. 如对您有所帮助,我们不胜荣幸! ************************************************************************* 本文属NetJava.cn中的Velocity中文系列,本系包含如下文章: 《Velocity Java开发指南中文版》(Developer`s Guide) 《Velocity模板使用指南中文版》(User`s Guide) 《Velocity Web应用开发指南中文版》(Web Application Guide) 《VTL语法参考指南中文版》(VTL Reference) 《DB4O中文系列之起步篇》 . . . 更多资料请访问http://www.netjava.cn/ 下载. ************************************************************************** 译者: javaFound Mail: javafound@gmail.com NetJava.cn@gmail.com ************************************************************************* 目 1.本文目地和使用对象... 2 2.什么是Velocity?. 3 3.Velocity能为你做什么?. 3 1.一个Mud Store Example. 3 4.Velocity Template Language (VTL): 介绍... 4 5.输出第一个VTL页面!. 4 6.Comments(注释). 5 7.References(引用)5 1.Variables(变量). 5 2.Properties(属性). 6 3.Methods(命令)... 6 4.属性引用中的属性查找规则... 6 8.Formal Reference Notation(正规引用格式注意事项). 7 9.Quiet Reference Notation(静态引用输出). 7 10.Getting literal( 语义问题)8 1.Currency(货币标志). 8 2.Escaping Valid VTL References(封装有效的引用). 8 11.Case Substitution(可选的格式)9 12.Directives(指令符号)10 1.#set指令... 10 2.Literals (语义解析)12 3.Conditionals(条件判断). 13 4.Loops(循环). 16 3.Include(引入). 17 6.Parse(解析模板). 18 7.Stop. 18 8.Velocimacros(宏调用). 18 13.注掉 VTL Directives. 20 14.VTL: 一般使用的格式... 22 15.Other Features and Miscellany(其它特性和细节)23 1.数学计算... 23 2.Range Operator. 23 3.Advanced Issues: Escaping and !. 24 4.Velocimacro Miscellany(关于宏的一些问题). 25 5.String Concatenation(连结字符串). 26 16.Feedback. 27 1.本文目地和使用对象 本文主要介绍如何在模板中使用Velocity功能强大的模板语言VTL(Velocity Template Language)用法有一个全面的认识,并掌握如何在模板中有效使用。同时,本文提供较多的例子帮您来学习它. 感谢您选择Velocity帮助您实现纯正的MVC系统构架。 2.什么是Velocity? Velocity 是一个基于java的模板引擎(template engine). 它可以让视图的设计者在web页面中引用java代码中定义的数据对象和命令。从而使Web designers和java开发者依照MVC思想(Model-View-Controller )开发系统,这意味着Web designers只须将精力注用于良好表现力的视图外观设计,而Java程序员则只要关心着如何写出高效简洁的java对象以实现业务逻辑-----Velocity会将他们组装到一起. 相比传统的jsp、PHP等脚本语言,Velocity彻底的将避免了在视图设计中出现的java代码, 从而保证了web site的长期可维护性. 一定要理解,Velocity是一个template engine的意思,它还可以从模板中生成SQL语句或其它脚本提供给web pages. 它也可以独立使用---做为一个工具类(utility class)用来生成源代码、报表、邮件模板等---在有需要重复的视图情况下,你应想到使用Velocity.Apache站点提供的另外一个框架Turbine 可以和Velocity有效结合以实现true MVC model. 3.Velocity能为你做什么? 1.一个Mud Store Example 假设你是一个page designer 在为一个在线商店设计页面. 我们称这个项目为 "The Online Mud Store".业务发展还不错,客户会订购不同类型的MuD,每个客户都会用自己的帐号密码login,查看选择他们订购的MuD,查看订单,但还有些忠诚用户会购卖不太流行的MuD----这些不需要出现在页面中显眼的地方。当然,The Online MuD Store必须把每个客户资料及订购信息记录到DB中,现在的问题是,如何让某个客户login后就看到他感兴趣的信息? 使用Velocity!我们为每个客户定制一个页面!这听起来工作量巨大,让我们试试:. 使用Velocity的 VTL 如下来设计 web page: <HTML> <BODY> ##指定用户名字 欢迎你: $customer.Name! <table> ###输出用户喜好的MuD #foreach( $mud in $mudsOnSpecial ) #if ( $customer.hasPurchased($mud) ) <tr> <td> $flogger.getPromo( $mud ) </td> </tr> #end #end </table> 使用VTL设计页面就是这么简单!文档《VTL参考中文版》中有更全面的VTL语言介绍,掌握这些,你将会全面体会到Velocity的威力. 4.Velocity Template Language (VTL): 介绍 The Velocity Template Language (VTL)目标是提供一个简洁,易学的方法将动态内容展现到web page上. a web page设计者可以没有任何编程经验就可以在一天内学会使用它增强你的站点的展示力!. VTL使用引用(references )这种方式将dynamic content(动态内容,一般指java代码生成的数据对象)加入到你的web site,Velocity中的变量(variable)只是refernce中的一种. Variables是用来描述从引入到视图模板中的java数据对象。当然,java代码也可以从模板的VTL中获取数据.以下是一个写在HTML中的VTL变量: #set( $a = "Velocity" ) VTL声明( statement),所以的VTL statement都是以#开头,且包含一个指示符(这里是set),当客户访问你的页面时, the Velocity Templating Engine将搜索页面中的所有 # 符号,如果确定这是一个VTL声明时就按一定规则处理动态内容, 符号#仅仅只是表明这可能是一个VTL声明. 符号# 所跟的set我们用“指示符”这一名词来称呼它(随后介绍更多的指示符), set 指示符使用一个表达式(expression) (包含在一对括号里) –将一个值 value (这里是Velocity)付给变量a,(变量名在左边,值在右边,用=组合起来). 在以上的例子中,变量是a ,而符号“$”表明它是一个变量,Velocity中所有变量以符号”$”开头,所付的值要用双引号括起, 这个值中还可以再添加Velocity变量,如"Hello $name",输出的将是name变量所付的值。 这是理解VTL基础的规则: 以$开头的表示“引用”意思是取得一些东东.而”指示”(Directives)则以#开头来表示,有点“做些什么动作”的意思. 如上便, #set 用来指定值给一个变量名$a, 以“$”标示的变量名a的值就是"Velocity". 5.输出第一个VTL页面! 有你的HTML文档的任何地方,都可以引用一个变量名来输出值, 如下例, 先给变量名foo 赋值为Velocity,然后将它输出到页面中. <html> <body> #set( $foo = "Velocity" ) Hello $foo World! </body> <html> 在这个页面上,你看到的将是 "Hello Velocity World!". 为了让查板中的VTL指令更易读, 我们强烈建议你每行一条VTL指令,当然这不是必须的. 关于 set directive的更多功能我们随后再讨论. 6.Comments(注释) Comments可以让你在模板中包含对VTL或其它问题的说明描述以便与阅读和理解.---但它并不会在最终输出的web pages中看到.如下示例是VTL中的一行注释. ## This is a single line comment. 单行注释是以## 开头的一行文字.如要写下多行注释,就要像下面那样,将它们放入#**#间: This is text that is outside the multi-line comment. Online visitors can see it. #* Thus begins a multi-line comment. Online visitors won't see this text because the Velocity Templating Engine will ignore it. *# 不需要太复杂了,这两种方式己足够你给自己的页面加上充分的说明。 7.References(引用) VTL中有三种references:变量引用(variables),属性引用(properties)和命令引用(methods). 做为一个使用VTL的设计者, 你和你的java软件工程师必须就模板中引用的特定名了(就是$后的名字)达成一致的协议!这样,模板和java代码才可按照你们的意图去结合以输出正确的内容. 所有的引用在模板中都表现为一个字符串. 假设一个引用变量 $foo 的值事实上是一个int, Velocity engine在处理时将调用它的 .toString() 去解析这个字符串所代表的对象(int). 1.Variables(变量) 简单的说变量以"$" 开后,后面跟一个VTL指示符( Identifier).一个合法的VTL指示符是以字母开头,后面可以是以下任意字符: alphabetic (a .. z, A .. Z) numeric (0 .. 9) hyphen ("-") underscore ("_") 以下是正确的VTL变量名: $foo $mudSlinger $mud-slinger $mud_slinger $mudSlinger1 当VTL中的一个变量如 $foo, 这个变量可以在模板中提取它自己的值通过set 指示符,或者从java代码中.比如,如果需java中的变量foo的值为bar,给模板中所有输出$foo声明的值都成为bar.当然,在模板中使用如下VTL也可以达到这个目地。 #set( $foo = "bar" ) 2.Properties(属性) VTL的第二种引用,属性引用,注意”属性”具有相对固定的格式. 它也是以$开头的合法VTL指示符,随后是”变量名字.变量属性”. 如下例: $customer.Address $purchase.Total 第一个例子, $customer.Address.我们设想可能在两种意思.首先它可能在查找customer引用的一个hashtable中的以“Address”为key关联的一个数据对象.另外他可能表示的是java对象customer中的getAddress()这个命令取得的结果(当然也可写成 $customer.getAddress()). 当客户请求Web页面中Velocity将根据具体的customer类型输出. 3.Methods(命令) 在java 代码中定义命令是最通常的事, 像执得一组方程式计算成本,读取一个文件等. 命令引用和其它引用一个也是一个一般的VTL声明,看如下的例子可能会更快的理解: $customer.getAddress() $purchase.getTotal() $page.setTitle( "My Home Page" ) $person.setAttributes( ["Strange", "Weird", "Excited"] ) 前两个例子 -- $customer.getAddress() and $purchase.getTotal() – 可以等同与属性引用情况: $customer.Address and $purchase.Total. 如你猜对了这点,呵,你还蛮聪明!同时,他们是等同与java对象coustomer的getAddress()命令调用。后面两个引用呢,也会直接对应java 对象的对应命令,不同的是传入了命令参数。 4.属性引用中的属性查找规则 前己提及,属性可以引用到对象的命令. Velocity会使用合适的策略选择引用到的命令. 它会根据协定的命令命令格式查找. 无论属性引用的的名字是否大小写,Velocity都有固定的查找规则.如在$customer.address引用时,查找顺序是: getaddress() getAddress() get("address") isAddress() 对于VTL中大写的属性名Address引用,将是: getAddress() getaddress() get("Address") isAddress() 8.Formal Reference Notation(正规引用格式注意事项) 以上是简洁格式引用的介绍,规则的格式像下面,如你看到的变量名需要放到{}中: ${mudSlinger} ${customer.Address} ${purchase.getTotal()} 大多数情况下,简洁格式引用足以满足使用,但有些情况下,必须使用正规格式引用. 假设你构造的一个字符串中要包括有 $vice 变量的值. 你觉得以下两种写法会是同样的结果吗: 1.Jack is a $vicemaniac. 2.Jack is a ${vice}maniac. 这样,Velocity就知你要的是 $vice, 而不是 $vicemaniac变量,正规引用格式一般用于在模板中直接调整字符串内容. 9.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}"/> 10.Getting literal( 语义问题) 一般情况下,velocity使用$,#字符来标志它的声明,但有时,HTML中因为某种其它意图,也会写出这样的字符,我们讨论如何消除这种语义歧义问题. 1.Currency(货币标志) 如美元 $2.50!这样的写法出现到模板中, VTL处理时是不会出错,会正确的输出$2.50!这个你想要的结果。为什么呢?一个合法的VTL标示符是以一个字母开头的,我们前面己说过. 2.Escaping Valid VTL References(封装有效的引用) 如下示,如果没有#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 11.Case Substitution(可选的格式) 至此,你对velocity的refenerce己比较熟悉了, 你可以在你的模板中开始应用这些功能. 但你还可以知道的是Velocity references从java语法中汲取了一些优点以便模板设计者更容易使用VTL.比如: $foo $foo.getBar() ## 等同于 $foo.Bar $data.setUser("jon") ##等同于 #set( $data.User = "jon" ) $data.getRequest().getServerName() ##等同于 $data.Request.ServerName ## is the same as ${data.Request.ServerName} 这里示例了你可选的一些引用方式. VTL汲取了java语法和java bean的一些简洁语法以解析java代码中Context中的对象和这些对象的命令及属性---这样,一个java对象的所有功能都可以展示到视图中了. Velocity也借见了java Bean的规范(Bean specifications defined by Sun Microsystems), 是大小写敏感的; 但Velocity会尽可能的帮你修正错误. 当命令 getFoo() 通过指令 $bar.foo在模板中引用时,Velocity的搜索规则我们在前面己讲了,你还记得是什么吗?. 注意:模板中引用的必须是通过java Bean中的getter/setter 实现的,而直接的java对象的数据域是不能直接引用的,如 $foo.Name 会解析到 class Foo's getName() 的实例方法,但不会解析到Foos类的 public Name 这个实例变量. 12.Directives(指令符号) 模板设计者使用“引用“生成动态内容, 指令(directives) – 简单的说就是设计者在模板中操作java对象—让视图设计者全面控制输出内容的格式. 指令总是以 #开头后面紧跟具体的指令符. 就像引用一样(指令的一种),可以将指令理解为”表示这里是一个什么东东).如下例生成一个出错提示: #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 相关资源:敏捷开发V1.0.pptx
转载请注明原文地址: https://www.6miu.com/read-5049375.html

最新回复(0)