Velocity语法强化56之强大的宏

#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中查找元素的过程. 


(关于宏的一些问题)

这是一些简短的问题总结,也许你先要有这样一个概念:. 'Velocimacro' 就像一个‘VM’。 

可否用一个指示符做为另外一个指示符运算的参数? 

如 : #center( #bold("hello") ) 

No. 指示符不是有效的参数但你可以这样实现你想要的: 

#set($stuff = "#bold('hello')" )

#center( $stuff )

或者: 

#center( "#bold( 'hello' )" )

上面这个例子中,参数是在调用的宏中生成的.不是调用者传入的. 看看下面的例子 : 

#macro( inner $foo )

  inner : $foo

#end

#macro( outer $foo )

   #set($bar = "outerlala")

   outer : $foo

#end

#set($bar = 'calltimelala')

#outer( "#inner($bar)" )

输出将是: 

Outer : inner : outerlala

因为 "#inner($bar)" 是发生在 #outer()内部的!

可否通过 #parse()来注册一个宏 ? 

宏必须在模板使用前定义好.前面己有一个关于此问题的建议,#parse()是运行时执进的,JVM查找对象的顺序不一定会全按我们预计的执行。 

什么是宏的自动重新装载? 

这是由配置参数决定的, 为方例开发者,在生产环境中则不需要 : 

velocimacro.library.autoreload 

默认的是false.当设为true中,需要设定chcheing参数; 

<type>.resource.loader.cache = false 

(具体配置请见开发指南,如下是一个配置的例子) 

    file.resource.loader.path = templates

    file.resource.loader.cache = false

    velocimacro.library.autoreload = true

    

注意:Don't keep this on in production. 


你可能感兴趣的:(Velocity语法强化56之强大的宏)