`
zzc1684
  • 浏览: 1223082 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

FreeMarker自定义TemplateDirectiveModel

阅读更多

在采用FreeMarker做前台视图模板的情况下,我们可以通过<#include>标签和自定义宏来解决很多重复性工作。

 

一个简单的FreeMarker宏:

 

<#macro sayHello name="">
    hello ${name}
</#macro>

 然后通过如下的形式调用:

 

 

    <@sayHello name="shannon" />  

 不过这种在模板页中定义的宏能力有限。【1】假设,我们很多页面都要输出一个热门排行框,而排行数据需要从controller层动态获取,我们可以用这 种宏来完成所有的展示工作,但前提是相应的controller和接口中层需要预先将这些排行数据放到model中去,因此对于后端来说这也是一个重复性 的工作。那么有没有一种方式可以让后端也脱离这种重复工作呢?答案是肯定的,这也是写这篇博客的目的。

 

 

在一个偶然的机会发现jeecms项目中用到了这种方式,于是借鉴了一番。

 

FreeMarker不仅可以在前端的模板页中定义宏,还可以通过扩展其接口在后端实现宏,这有什么好处呢?这种方式就好比让你的模板页具备了从前 端再次回到后端的能力。这样我们就能很好的解决【1】处的假设,我们无需在各个controller的各个接口中去重复的向model中添加所需的排行数 据,而是当FreeMarker渲染模板页时遇到相应的宏它可以回到后端去调用相应的方法取到所需的数据。例子如下:

    import freemarker.core.Environment;  
    import freemarker.template.ObjectWrapper;  
    import freemarker.template.TemplateDirectiveModel;  
      
    /** 
     * FreeMarker自定义宏 
     * 获取App下载排行列表 
     * 参数包括 length(列表长度) mtypeCode(主类型代码) typeCode(小类型代码) rankMode(排行模式1、2、3) 
     * @author shannon 
     * 
     */  
    public class FMAppRankDirective implements TemplateDirectiveModel {  
      
        @Resource(name = "appRankService")  
        private AppRankService appRankService;  
          
          
        @SuppressWarnings("unchecked")  
        @Override  
        public void execute(Environment env, Map params, TemplateModel[] loopVars,  
                TemplateDirectiveBody body) throws TemplateException, IOException {  
            //DirectiveUtils是借用jeecms项目中的工具类,主要是因为它集成了一些异常处理功能,  
            //其实完全可以不用它,params是个Map,自己通过key取值就可以了,做一下空值判断  
            Integer length = DirectiveUtils.getInt("length", params);  
            Integer mtypeCode = DirectiveUtils.getInt("mtypeCode", params);  
            Integer typeCode = DirectiveUtils.getInt("typeCode", params);  
            Integer rankMode = DirectiveUtils.getInt("rankMode", params);  
            ArrayList<App> rankList = appRankService.getRankList(length, mtypeCode, typeCode, rankMode);  
              
            env.setVariable("appRankList", ObjectWrapper.DEFAULT_WRAPPER.wrap(rankList));  
            if (body != null) {  
                body.render(env.getOut());  
            }  
        }  
    }  

 通过实现FreeMarker的TemplateDirectiveModel就在后端实现了一个自定义的宏,这个宏的功能很简单,只是根据给定的参数将排行数据“appRankList”放到model中去,然后模板页中就可以使用这个变量了。

FreeMarker的配置参数中需要将这个宏加入进去。

    <bean id="appRankDirective" class="com.shannon.example.rank.util.FMAppRankDirective" />  
    <bean id="freemarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
        ……其他配置略……  
        <property name="freemarkerVariables">  
            <map>  
                ……其他配置略……  
                <entry key="appRankDirective" value-ref="appRankDirective"/>  
            </map>  
        </property>  
    </bean>  

 在模板页中使用:

    <#-- 应用下载排行框,title为该框的标题,length为排行列表长度,mtypeCode为主类型代码,typeCode为小类型代码,rankMode为排行方式   
    1为总下载量,2为月下载量,3为昨日增长下载量  
    -->  
    <#macro appRankBox title="" length=10 mtypeCode=1 typeCode=-1 rankMode=1>  
          <@appRankDirective length=length mtypeCode=mtypeCode typeCode=typeCode rankMode=rankMode />  
            <h3 class="box-title">${title}</h3>  
        <div class="box">  
          <ul class="row-list">  
            <#list appRankList as item>  
            ……详细输出内容略……  
            </#list>  
            </ul>  
        </div>  
    </#macro>  

 这里我在模板页中又定义了一个宏,负责内容及样式的输出,因为模板页中的宏比较直观,让后端的宏只负责拿数据。其他页面直接使用“appRankBox”就可以了,然后由它来调用后端的“appRankDirective”宏来拿数据。

这样,controller就从重复工作中脱身了。

 

你好,咨询一个问题。templateDirectiveBody对应的render方法到底是干什么用的。

回复simmon_guan:本实例中的用法是这样的形式:
<@appRankDirective ... />
就没有body。
如果用法如下:
<@appRankDirective ... > ... </@appRankDirective>
这标签中间的内容就是body
分享到:
评论

相关推荐

    freemarker 自定义freeMarker标签

    1. 创建自定义指令类:你需要创建一个继承自`freemarker.template.TemplateDirectiveModel`的Java类。这个类将定义你的自定义标签的行为,包括如何处理输入参数,如何处理模板模型数据,以及如何生成输出。 2. 注册...

    Freemarker 自定义标签 简单案例

    在这个"Freemarker自定义标签简单案例"中,我们将深入探讨如何利用Freemarker进行模板设计,并结合自定义标签来增强模板的功能。 首先,让我们理解Freemarker的基础知识。Freemarker是一个与语言无关的模板引擎,它...

    spring mvc freemarker 自定义标签

    下面将详细介绍Spring MVC与Freemarker自定义标签的使用。 首先,我们需要了解Freemarker的基础。Freemarker是一个基于模板的语言,它的主要任务是根据数据模型生成输出。在Spring MVC中,Freemarker模板通常用于...

    实现通过jfinal框架自动扫描freemarker的自定义标签.zip

    本资源包的核心内容是教你如何在JFinal项目中实现FreeMarker自定义标签的自动扫描和注册,从而提升模板引擎的功能和灵活性。 首先,我们需要理解自定义标签的概念。在FreeMarker中,自定义标签允许开发者扩展其内置...

    代码生成器必备jar包:Freemarker-2.3.23

    例如,你可以自定义一个`&lt;@myDirective ...&gt;`,然后在Java代码中实现对应的`TemplateDirectiveModel`,这样在模板渲染时,`myDirective`就会被正确执行。 在描述中提到"Freemarker-2.3.23低于2.3没有上面的命名空间...

    freemark 自定义标签 总结

    本篇文章将对Freemarker自定义标签进行深入的总结。 1. **自定义标签基础** 自定义标签在Freemarker中被称为`Custom Tags`,它们通过`&lt;@...&gt;`语法来调用。这些标签通常是由Java代码实现的,它们可以处理复杂的逻辑...

    freemarker教程

    1. 自定义指令:通过继承`TemplateDirectiveBody`和`TemplateDirectiveModel`,可以创建自己的模板指令,增强模板功能。 2. 国际化支持:Freemarker能处理资源包(properties文件),通过`...

    freemarker-api.rar_Freemarker java api_freemarker_freemarker api

    4. `TemplateDirectiveModel`和`TemplateMethodModel`:这两个接口用于自定义模板指令和方法,使得在模板中可以调用Java方法或执行自定义逻辑。 5. `TemplateScalarModel`、`TemplateNumberModel`、`...

    freemarker获取数据

    5. 自定义指令:通过实现`TemplateDirectiveModel`,可以创建自定义指令,增强模板功能。 四、最佳实践 1. 保持模板简洁:避免在模板中进行复杂的逻辑处理,将业务逻辑留在后端。 2. 使用`ModelAndView`或`Map`...

    FreeMarker概述API

    4. **`TemplateDirectiveModel`**:这是FreeMarker中定义自定义指令的接口。如果你需要在模板中使用自定义的行为,可以实现这个接口,然后将它放入数据模型中供模板调用。 5. **`TemplateMethodModelEx`**:用于在...

    freemarker及jeecms标签使用学习文档

    - **自定义函数和标签**:通过`TemplateMethodModelEx`接口实现自定义方法,`TemplateDirectiveModel`接口实现自定义标签。 - **模板缓存**:提高性能,减少不必要的模板编译。 3. **Jeecms标签使用** - **...

    FreeMarker入门指南API文档(中文版)

    4. **TemplateDirectiveModel**: 定义自定义指令的接口,允许扩展FreeMarker的功能。 **使用步骤** 1. 创建`Configuration`实例,配置FreeMarker。 2. 加载模板文件,得到`Template`对象。 3. 创建数据模型,通常...

    springboot-freemarker-master.rar_freemarker_springboot

    - 自定义指令:可以通过实现`TemplateDirectiveModel`接口,创建自定义的Freemarker指令。 - 逻辑控制:Freemarker提供了丰富的逻辑控制结构,如`&lt;#if&gt;`、`&lt;#choose&gt;`、`&lt;#switch&gt;`等。 - 数据类型转换:...

    freemarker模板

    4. `TemplateDirectiveModel`和`TemplateMethodModel`: 分别表示指令和方法模型,用于实现自定义的模板扩展。 通过阅读源码,我们可以学习到FreeMarker如何解析模板,如何处理变量和表达式,以及如何执行自定义...

    freemarker的api

    4. **自定义函数和标签**:Freemarker支持自定义函数(`TemplateMethodModelEx`)和标签库(`TemplateDirectiveModel`),你可以扩展Freemarker的功能,使其更符合项目需求。 三、模板语法 Freemarker的模板语法...

    freemarker入门代码

    - **自定义指令**:通过实现`TemplateDirectiveModel`接口,可以扩展FreeMarker的功能,创建自定义的指令。 - **国际化(i18n)**:结合资源文件,FreeMarker能轻松支持多语言环境。 通过以上介绍,你已经对...

    FreeMarker API源代码

    开发者可以通过实现`TemplateDirectiveModel`接口创建自定义的FreeMarker指令,以扩展其功能。 学习FreeMarker API源代码有助于深入理解其内部工作原理,更好地优化模板处理,以及在遇到问题时进行调试。通过阅读...

    SpringMVC+freemarker

    - **自定义标签**: Freemarker 允许创建自定义标签,实现特定功能,如表单验证、数据格式化等。这通常通过编写 Java 代码,封装成宏库,然后在模板中调用。 4. **自定义标签的创建与使用** - **创建标签库**: ...

    Freemarker 2.3.23 中文手册

    - **自定义指令**: 通过实现`TemplateDirectiveModel`接口,可以创建自定义的模板指令。 - **标签库**: 集成自定义标签库,例如Spring的Tiles和JSP的JSTL标签。 9. **与其他技术集成** - **Spring MVC**: Spring...

    freemarker权威版 网站静态化

    4. **自定义指令**: 如果需要扩展Freemarker的功能,可以通过实现`TemplateDirectiveBody`和`TemplateDirectiveModel`接口来自定义指令。 总的来说,深入理解和掌握Freemarker API,对于提升Web应用的性能和开发...

Global site tag (gtag.js) - Google Analytics