zoukankan      html  css  js  c++  java
  • 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或其它模板语言的同学有帮助。

  • 相关阅读:
    MySQL数据库分区修改【原创】
    浅谈测试rhel7新功能时的感受及遇到的问题【转载】
    htop安装步骤【原创】
    Shell脚本,自动化发布tomcat项目【转】
    shell编程之服务脚本编写,文件锁以及信号捕获
    如何清除jboss缓存
    device-mapper: multipath: Failing path recovery【转载】
    ajax 设置Access-Control-Allow-Origin实现跨域访问
    HTML5中Access-Control-Allow-Origin解决跨域问题
    深入理解JavaScript系列(结局篇)
  • 原文地址:https://www.cnblogs.com/j2eetop/p/4612583.html
Copyright © 2011-2022 走看看