`
oznyang
  • 浏览: 160936 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

原创freemarker功能增强小项目freemarker-sweet,实现了类似jsp tag的宏的嵌套调用和复杂参数设置

阅读更多
freemarker的宏功能非常强大,但是也有局限性,比如不能像jsp tag一样,访问父tag的参数,不利于复杂macro的封装,闭门研究freemarker代码三天,基本实现了宏的嵌套调用问题,特分享之

比如下面这个tag嵌套,是一个对ext grid的封装:
  <g:list id="gridobj" width="100%" checkbox="true"
			keyField="NEW_ID" splitInfo="splitParam"
			rowdbclick="rowdbclick" contentHeightOffset="-100">
			<g:query>
				<g:queryItem label="名称" name="NEW_TITLE" />
				<g:queryItem label="时间(起)" itemType="datefield" name="NEW_DATE1" />
				<g:queryItem label="时间(止)" itemType="datefield" name="NEW_DATE2" />
			</g:query>
			<g:field fieldname="NEW_ID" header="编号" width="80" hidden="true" />
			<g:field fieldname="STATUS" header="图片" width="35" renderer="statusHandler"/>
			<g:field fieldname="NEW_TITLE" header="项目名称" width="230" />
            <g:field fieldname="NEW_SUMMARY" header="新闻摘要" width="300" renderer="summaryHandler"/>
			<g:field fieldname="NEW_DATE" header="时间" width="85" renderer="dateformat" />
			<g:field fieldname="IMAGE_URL" header="新闻路径" width="100" hidden="true"/>
		</g:list>

但是freemarker macro没有这个能力,在宏的嵌套body中,只能在宏中通过<#nested>来访问标签之间的文本,或者直接用参数传过去,而不能在tag之间设置tag的参数,宏的局部变量对宏tag之间的body也是隐藏的

为此我开发了两个directive
ExposeDirective
ParamDirective

ExposeDirective实现了把当前宏的macroContext导出到全局变量,同是如果发现自己被宏调用嵌套,则创建一个变量保存父宏的macroContext,达到访问父宏上下文的目的
  Macro.Context mc = env.getCurrentMacroContext();
        if (mc == null) {
            throw new TemplateException("macro context not found,this directive must be call in macro", env);
        }
        List stack = DirectiveHelper.getElementStack(env);
        Object macroCall = null, parentMacroCall = null;
        for (int i = stack.size() - 1; i > -1; i--) { //遍历当前运行时堆栈,找到当前宏的UnifiedCall
            if (stack.get(i) instanceof Macro) {
                Object call = stack.get(i - 1);
                if (macroCall == null) {
                    macroCall = call;
                } else {
                    parentMacroCall = call;
                    break;
                }
            }
        }
        DirectiveHelper.exposeMacroContext(env, macroCall, mc);//暴露当前宏local变量上下文到全局上下文
        if (parentMacroCall == null)
            return;
        Macro.Context parentMc = (Macro.Context) DirectiveHelper.getMacroContext(env, parentMacroCall);//获取父宏上下文
        if (parentMc != null)
            mc.setLocalVar(DirectiveHelper.getParam(params, "parent", "parent"), parentMc.getLocals());//在当前宏上下文中保存一个叫parent的变量,值为父宏的local变量

ParamDirective则根据当前的调用堆栈找到macroContext,从而可以访问到宏的局部变量,实现了宏的嵌套使用,并且支持复杂的参数设置

请看例子:
设置变量
<#macro outer name="ozn" age="27" sex="boy">
<@expose/>
<#nested>
</#macro>

<#macro inner parent={}>
<@expose/>
<@param name="parent.name" value="cici"/>
${parent.name}
</#macro>

<@outer><@inner/></@>


使用body来设置变量值
<@param name="addr.area">${addr.country}</@>


删除变量
<#macro outer name="ozn" age="27" sex="boy">
<@expose/>
    <#nested>
</#macro>

<#macro inner parent={}>
<@expose/>
<@param name="parent.name" action="remove"/>
${parent?keys?size}
</#macro>

<@outer><@inner/></@>


添加变量
<#macro hello name=["ozn","cici"]>
<@expose/>
<#nested>
${name?size}
</#macro>
<@hello><@param name="name" value="me" action="add"/></@>


更多例子请看代码里面的testCase

另附上覆盖率测试图

有任何问题,请不吝赐教

代码托管于:
http://code.google.com/p/freemarker-sweet/
分享到:
评论

相关推荐

    freemarker.jar

    camel-freemarker-1.6.4.jar, camel-freemarker-2.8.1.jar, com.springsource.freemarker-2.3.15.jar, com.springsource.freemarker-sources-2.3.15.jar, freemarker-1.4.1.jar, freemarker-2-3-18.jar, freemarker-...

    freemarker-2.3.30-API文档-中文版.zip

    赠送jar包:freemarker-2.3.30.jar; 赠送原API文档:freemarker-2.3.30-javadoc.jar; 赠送源代码:freemarker-2.3.30-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.30.pom; 包含翻译后的API文档:...

    基于springboot+MyBatis+FreeMarker等技术项目------恋家房产平台(项目包含前后台)

    其中可能涉及一些链家网、H-ui等相关的信息,在这里说明,本项目仅供交流学习,不得用于商业传播)基于springboot+MyBatis+FreeMarker+redis+nginx等技术的JavaWeb项目------恋家房产平台先简单放几张项目的图吧,...

    apache-freemarker-2.3.27-incubating-bin.tar.gz

    6. **指令(Directive)**:用于控制模板的逻辑,如#if、#foreach等,它们可以嵌套使用,实现复杂的条件判断和循环。 7. **控制结构(Control Structures)**:类似于编程语言中的流程控制语句,如条件语句和循环...

    JavaEE源代码 freemarker-2.3.8

    JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-...

    freemarker_lastest最新最全--文档+安装包+操作手册

    在使用Freemarker时,首先需要配置和初始化`freemarker.template.Configuration`对象,设置模板目录和输出字符集等参数。然后,创建一个`Template`对象,加载模板文件。接着,准备一个数据模型,通常是Java对象或Map...

    freemarker-2.3.30-API文档-中英对照版.zip

    赠送jar包:freemarker-2.3.30.jar; 赠送原API文档:freemarker-2.3.30-javadoc.jar; 赠送源代码:freemarker-2.3.30-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.30.pom; 包含翻译后的API文档:...

    freemarker-2.3.31-API文档-中文版.zip

    赠送jar包:freemarker-2.3.31.jar; 赠送原API文档:freemarker-2.3.31-javadoc.jar; 赠送源代码:freemarker-2.3.31-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.31.pom; 包含翻译后的API文档:...

    freemarker-2.3.22

    `freemarker.jar`是Freemarker库的二进制文件,它是实际运行时需要导入到Java项目的类路径中的,以便使用Freemarker的功能,如创建模板、解析数据模型并生成最终输出。 `source`目录可能包含了Freemarker 2.3.22的...

    jsp、freemarker、velocity简介和对比

    ### jsp、freemarker、velocity简介和对比 在Java Web开发领域,模板引擎是连接后端业务逻辑与前端展示层的重要桥梁。本文将重点介绍三种常用的Java Web模板引擎:JSP(Java Server Pages)、Freemarker以及...

    freemarker模板技术生成复杂word文档---解决了编码问题

    经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。 word的几个主要xml标志 w:body 正文内容 w:p 一个段落 w:tbl 表格数据 w...

    spring-boot-starter-freemarker-1.5.4.RELEASE.jar

    spring-boot-starter-freemarker-1.5.4.RELEASE.jar

    freemarker生成静态页面------内含使用说明

    Freemarker是一个强大的模板引擎,常用于Web应用中动态生成HTML或其他类型的静态页面。它采用声明式编程方式,...在实际开发中,结合具体的项目需求,可以进一步探索和优化Freemarker的使用方式,实现更复杂的功能。

    freemarker-2.3.28.jar

    这个"freemarker-2.3.28.jar"文件可能是Eclipse插件的一部分,意味着它可以方便地在Eclipse环境中配置和使用Freemarker,提供代码提示、自动完成、错误检查等功能,从而提高开发效率。 在实际应用中,开发者通常会...

    freemarker各种版本的jar包

    - 这个版本可能包含了一些基本的功能,如模板语言的语法,变量、表达式和控制结构。 - 它可能已经支持了数据模型绑定,允许开发者将Java对象的数据传递给模板进行渲染。 - 可能包括了基本的错误处理机制和调试...

    原创 用FreeMarker宏 和 Jquery 做树(Hbiernate和JDBC版)

    标题 "原创 用FreeMarker宏 和 Jquery 做树(Hbiernate和JDBC版)" 描述了如何使用FreeMarker模板引擎的宏功能,结合jQuery库,创建一个可展示层次结构数据的树形视图。在这个过程中,可能涉及了两个主要的技术:...

    freemarker-2.3.22.jar

    freemarker-2.3.22.jar用于生成word模板核心工具包,非常好用!详细操作使用,请参考我的文章链接:https://blog.csdn.net/qq_45978154/article/details/125065400?spm=1001.2014.3001.5502

    freemarker 实现宏分页

    FreeMarker 是一个强大的模板引擎,常用于Java Web开发...记住,学习和理解FreeMarker的宏机制是关键,这有助于你在实际项目中灵活应用和扩展分页功能。通过这种方式,你可以创建一个既高效又易于维护的分页解决方案。

    freemarker最新中文手册更新时间 2015-10-07

    5. **自定义指令**:可以扩展FreeMarker,实现自定义的模板指令和函数。 ### 学习资源 这份2015年10月7日的FreeMarker中文手册是学习和解决问题的重要参考,其中详细介绍了FreeMarker的语法、配置、最佳实践等内容...

    Java项目中利用Freemarker模板引擎导出--生成Word文档

    在项目中难免和各种数据报表打交道,如导出XX申请表,登记表,推荐表之类。就可以通过现有信息导出Word文档。基于Java语言来导出Word文档的方式也有很多种,如Jacob,Apache POI,Freemarker,PageOffice,java2word...

Global site tag (gtag.js) - Google Analytics