`
j2eetop
  • 浏览: 64386 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Velocity宏定义的坑与解决办法

 
阅读更多
使用Velocity,当然就免不了要使用宏,或者说使用Velocity而不使用其宏,就相当于废了Velocity一半以上的武功,非常可惜的。怎么使用Velocity的宏呢,才最大程度的发挥其作用但是又避免掉入其中的坑呢?且听悠然乱弹乱弹:
官方文档中,关于Macro是这么说的:
#macro - Allows users to define a Velocimacro (VM), a repeated segment of a VTL template, as required
Format:
# [ { ] macro [ } ] ( vmname $arg1 [ $arg2 $arg3 ... $argn ] ) [ VM VTL code... ] # [ { ] #end [ } ]
  • vmname - Name used to call the VM (#vmname)
  • $arg1 $arg2 [ ... ] - Arguments to the VM. There can be any number of arguments, but the number used at invocation must match the number specified in the definition.
  • [ VM VTL code... ] - Any valid VTL code, anything you can put into a template, can be put into a VM.
Once defined, the VM is used like any other VTL directive in a template.
#vmname( $arg1 $arg2 )

当然,上面清晰的说明了怎么写Macro,也就是说可以写成:

1
2
3
4
5
#{macro}(macroName $varName1 $varName2)

##这里是模板内容

#end


也可以写成
1
2
3
4
5
#macro(macroName $varName1 $varName2)

##这里是模板内容

#end


当然参数个数可以是0..n个。OK,确实很简单,但是上面的说法实际上只解决了如何写出满足正确语法的宏,但是实际应用当中,如果不加以约束,可能就出现非常难以查找的问题。
比如下面定义了一个超链接的宏,由于id不是每次都用得到,因此id是可选参数,可以填,也可以不填:

1
2
3
#macro(link $href $id)
< a href="$!href"#if($id) id="$id"#end>$bodyContent</a>
#end


然后,就可以如下使用了:
1 #@link("www.tinygroup.com")TinyGroup#end


上面的写法有问题么??似乎没有什么问题,即使什么参数也不传,只写下面的调用方法:

1 #@link()#end


渲染的结果也会是:
1 <a href=""></a>


OK,如此说来,真的没有啥问题。 接下来,我们又要写一个图片链接的宏,同样的由于id不是每次都需要,我们把它写成可选的:

1
2
3
#macro(image $href $id)
< img src="$href"#if($id) id="$id"#end>
#end


在调用的时候,我们可以如下写:
1 #image("www.tinygroup.org/img/logo.gif")


也可以这样写
1 #image("www.tinygroup.org/img/logo.gif" "logoImage")


OK,一切都没有什么问题 但是我们想给首页上的Logo图片加个链接到首面上。
这个时候,我们会如下写:

1
2
3
#@link("www.tinygroup.org")
#image("www.tinygroup.org/img/logo.gif")
#end


渲染的结果也如我们所期望的
1 <a href="www.tinygroup.org"><img src="www.tinygroup.org/img/logo.gif"></a>


确实也如我们期望,正确的渲染了。 这个时候,我们忽然期望首页链接添加个id,期望利用JQuery对其进行一些动态处理,我们就把代码写成下面的样子:

1
2
3
#@link("www.tinygroup.org" "homepageLink")
#image("www.tinygroup.org/img/logo.gif")
#end


这个时候,我们去执行的时候,忽然发现,程序不能正确运行了,去查看一下渲染的最终结果,居然是:
1 <a href="www.tinygroup.org" id="homepageLink"><img src="www.tinygroup.org/img/logo.gif"id="homepageLink"></a>


这说明一个道理就是:
  • 外层的宏中的变量,在内层的宏中是可以访问的
  • 内层中的变量,如果与外层中宏的变量名冲突,如果有传入,则按传入的值,如果没有传入,则取上层中的值
正是基于上述原因,在Tiny UI框架中,所有宏定义,宏变量都必须前宏前缀,也就是说上面的两个宏定义要按下面的方式来进行定义:

1
2
3
#macro(link $linkHref $linkId)
< a href="$!linkHref"#if($linkId) id="$linkId"#end>$bodyContent</a>
#end



1
2
3
#macro(image $imageHref $imageId)
< img src="$imageHref"#if($imageId) id="$imageId<span></span>"#end>
#end


小结:
虽然原因及解决办法都非常简单,但是也是吃了亏之后才总结出来的,希望能对也使用Velocicty或其它模板语言的同学有帮助。
分享到:
评论

相关推荐

    velocity新手入门

    文档是velocity基本知识,语法运用,宏定义等,适合新手入门

    velocity-1.5.jar,velocity-1.6.2-dep.jar,velocity-tools-1.3.jar

    在这个版本中,Velocity提供了基本的模板引擎功能,包括变量替换、控制结构(如if、for、foreach)以及宏定义等。它支持JavaBean和Map对象的直接引用,并且通过Action接口可以方便地进行用户自定义操作。此外,...

    简单的velocity工程

    3. **宏定义与调用**:`#macro`用于定义可重用的代码块,`#invoke`用来调用宏。 4. **引入其他模板**:`#include`指令可以将另一个模板文件的内容插入当前模板中。 5. **注释**:Velocity支持两种注释,行内注释以`#...

    velocity插件与学习文档

    3. **宏库**: Velocity支持宏定义,宏可以理解为可重用的代码块,有助于提高代码复用性和可维护性。 4. **模板布局**: 可以使用Velocity设计模板布局,通过`#include`或`#parse`指令包含其他模板文件。 5. **模板...

    velocity的jar包

    4. **宏**:Velocity支持宏定义,宏类似于函数,可以在模板中重复使用,提高代码复用性。 5. **事件驱动的处理机制**:Velocity 提供了一套事件驱动的处理机制,允许用户自定义处理器对模板进行预处理或后处理,如...

    Velocity 和 FreeMarker区别

    - **Velocity**也有类似的宏定义`#macro(name param1 param2) ... #end`,但功能相对有限。 5. **转义**: - **FreeMarker**内置了多种转义功能,比如HTML转义、XML转义等,可以通过简单的指令实现。 - **...

    eclipse中velocity插件

    5. **宏库支持**:Velocity支持宏定义,插件可以帮助开发者管理和重用这些宏,提高代码复用率。 要安装Eclipse中的Velocity插件,你可以按照以下步骤操作: 1. 打开Eclipse,选择菜单栏的“Help” -&gt; “Eclipse ...

    velocity+ssi整合

    在实际应用中,Velocity通常被看作是更强大和灵活的解决方案,因为它提供了更丰富的表达能力、支持宏定义以及更易于维护的代码结构。而SSI由于其简单性,更适合处理轻量级的动态需求。在整合两者时,需要注意的是,...

    velocity document

    3. **宏定义与调用**:Velocity支持宏,类似于函数,可以重复使用一段模板代码。通过`#macro`定义宏,`#invoke`或`#m`调用宏。 4. **内置方法**:Velocity提供了一些内置的方法,如`escape()`用于转义特殊字符,`...

    velocity语法与使用方法

    Velocity还支持一些更高级的功能,比如宏定义和继承: - 宏定义可以视为一种函数,可以接受参数并返回结果。 - 继承允许一个模板继承另一个模板的结构和样式,这对于大型项目非常有用。 综上所述,Velocity是一种...

    velocity经典4pdf中文教程

    2. **《VTL语法参考指南中文版》**:VTL(Velocity Template Language)是Velocity的核心,此指南深入解析了VTL的所有语法元素,包括文本输出、变量引用、方法调用、条件语句、循环结构、宏定义和使用。对于开发者来...

    struts2整合velocity

    Velocity支持控制结构(如if、for)、宏定义以及变量引用等,使得模板编写更加灵活。 **3. 整合Struts2与Velocity** 为了整合这两个框架,我们需要进行以下步骤: - **配置Struts2的配置文件(struts.xml)**:在...

    velocity文档(Velocity1.4java开发指南中文版,Velocity1.4模板使用指南中文版中文版)

    4. **宏**:Velocity 支持宏定义,类似于 HTML 中的自定义标签,可以复用和封装代码,增强模板的模块化。 5. **指令集**:Velocity 提供了多种内置指令,如 #if, #foreach, #set 等,用于控制流程和处理数据。 ** ...

    velocity入门使用教程

    4. 宏:定义可复用的代码块称为宏,可以通过`#macro`指令定义,通过`#end`指令结束。 #### velocity.properties配置文件 velocity.properties是Velocity的配置文件,用于设置Velocity运行时的各种属性,比如模板...

    velocity中文

    - `#macro()`:定义宏,可重用的代码块。 - `#include()`:包含其他模板文件。 ### 3. Velocity上下文(Context) 上下文是Velocity中数据传输的核心,它负责在模板和Java后端之间传递信息。你可以向Context中添加...

    velocity 配置jar包

    - **宏库(Macros)**:Velocity 支持宏定义,可以将常用模板结构封装为可重用的宏,提高模板代码的复用性。 - **自定义指令(Directives)**:你可以通过扩展 Velocity,实现自定义的 VTL 指令,满足特定需求。 -...

    velocity和freemarker的比较

    - **优势**:Velocity的语法简洁,易于学习,支持宏定义,可以进行复杂的逻辑控制。由于它不直接暴露Java代码,使得模板更加安全,不容易引发编程错误。 - **应用场景**:Velocity常用于Web应用、邮件模板、文档...

    velocity的学习资料

    - 使用`#macro`定义宏,可重用代码片段。 - 注意模板的可读性和可维护性。 这个压缩包提供的资料应该涵盖了Velocity的基础和进阶知识,对于想要学习或提升Velocity技能的开发者来说,是一份宝贵的资源。通过深入...

    velocity总结

    - **“#”号的使用**:“#”号用于标识 Velocity 脚本中的各种语句,包括但不限于条件语句(`#if`, `#else`, `#end`)、循环语句(`#foreach`, `#end`)、宏定义(`#macro`, `#end`)以及包含(`#include`, `#parse`...

Global site tag (gtag.js) - Google Analytics