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或其它模板语言的同学有帮助。

时间: 2024-11-12 23:18:41

Velocity宏定义的坑与解决办法的相关文章

zookeeper集群查看状态时报错Error contacting service. It is probably not running的一些坑以及解决办法

最近在搭建mq集群时候需要用到,zookeeper,可是启动的时候显示成功了,查看状态的时候却报错了: 碰到这个问题也是研究好好半天才解决,这里就总结出一个快速解决办法! 首先,必须看日志: 报错信息一般是当前目录下这个文件中,打开查看是什么原因,基本上我碰见的两种:一种是端口占用,一种是找不到路由: 还有一种就是端口占用了,netstat -znpl |grep 2181 查看一下并关闭这个进程,默认端口是2181,zoo.cfg可配置 !!!!这里提示一下,zoo_sample.cfg必须改

常见的移动端H5页面开发遇到的坑和解决办法

转自:https://www.cnblogs.com/LiuJL/p/7744473.html 1.安卓浏览器看背景图片,有些设备会模糊. 用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢? 经过研究,是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率来显示网页,这样字会非常小,所以苹果当初就把iPhone 4的960640分辨率,在网页里只显示了480320,这样devicePixelRatio=2.现在android比较乱,有1.5的,有2的也有3的.

使用mysql innodb 使用5.7的json类型遇到的坑和解决办法

---------------------------------------------- #查询JSON的某个字段 select data -> '$.Host' from temp #创建虚拟列 ALTER TABLE temp ADD host varchar(128) GENERATED ALWAYS AS (json_extract(data,'$.Host')) VIRTUAL; #给虚拟列创建索引 ALTER TABLE temp ADD INDEX index_temp_hos

记一次开发过程中,iview遇到的一些坑以及解决办法

写在开头:本次项目采用的是vue2.0+iview3.0,最近公司没啥事,来总结一下开发过程中遇到的问题. 1.Modal关闭问题 需求背景:modal框里面是个form表单,点击确定之后,先验证form表单,验证通过则关闭modal框,验证不成功则提示用户,不关闭. 问题描述:本来刚开始想通过modal框v-model绑定的值(true或false)来进行控制,手动改之后,报错. 解决办法: 官方iview的modal组件的api里面有个loading属性,可通过控制loading的值来进行控

matlab2016b配置libsvm的各中坑及解决办法

Q1:matlab2016b不能自动关联m文件! A1: (1)首先准备好工具,工具链接:pan.baidu.com/s/1t_KaFZNOFln9m57sMBTrkQ:提取码:x49w. (2)下载之后解压,请阅读readme,按照操作流程进行. Note:运行reg文件的方式是,将matlab最小化(不退出),找到reg文件所在位置(就是压缩包后所在路径),双击就好了,然后关闭matlab,重启,则matlab已经关联m文件了,如果还没有成功,请关机重启电脑,再试一下,应该就能解决了. Q2

Sqlserver 2016 R Service环境安装的各种错误(坑)解决办法

相信很多朋友都会慕名Sqlserver 2016的R语言功能,将自己的数据库升级到Sqlserver 2016,但是当你安装完Sqlserver 2016的R语言组件之后,你会发现并不能直接使用,比如当你在SSMS中执行下面这段测试R语言命令的时候,Sqlserver 2016会各种报错... exec sp_execute_external_script @language =N'R', @script=N'OutputDataSet<-InputDataSet', @input_data_1

Ubuntu16.04编译Android6.0/cm13.0教程及相关错误解决办法

一.必备工作 1.安装依赖库 sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib git flex bison gperf build-essential libncurses5-dev:i386 tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 dpkg-dev libsdl1.2-dev li

《OpenGL编程指南第七版》学习——编译时提示“error C2381: “exit” : 重定义;__declspec(noreturn) 不同”错误的解决办法

解决办法一. #if defined(_WIN32) # ifndef GLUT_BUILDING_LIBextern _CRTIMP void __cdecl exit(int); 上面是glut.h中对exit的使用,意思是如果没有定义宏?GLUT_BUILDING_LIB,就使用它的exit,那我们就在项目的属性--预处理器 里定义这个宏,这样就不执行glut.h中的exit了,而只执行stdlib.h中的exit.这样也就不会冲突了.对了,还要在附加依赖项里手动加上?glut32.lib

配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler” 解决办法

今天遇到了这个问题, 电脑系统:vs2010 win7系统 iis7 我运行在iis中配置的那个网站后,报错:错误代码 0x800700b7 配置错误定义了重复的"system.web.extensions/scripting/scriptResourceHandler"节 这个问题原因在于window7的IIS默认用的是ASP.NET v4.0应用程序池. 解决方法:把这个网站的应用程序池的.netframework版本改为 v2.0的,如图: 1:选中应用程序池-->在右侧右