指令与函数开发

    指令是一种FreeMarker的扩展,既可以在模板中定义指令又可以用java类实现指令,在PublicCMS中对FreeMarker这种指令扩展方式进行了封装和延申。

    函数是一种FreeMarker轻量级扩展,也同样支持模板定义和java类实现。

    这些指令和函数既支持在模板中调用,也支持http方式请求调用,参数规则也保持一致,实现httpEnabled方法返回false可以禁用http方式,实现needAppToken方法返回true可以启用安全验证,只有后台维护->应用授权中授权的应用通过其token才可请求。

    这里主要讲解在PublicCMS中的封装进行java类扩展的方式,一个指令需要继承 com.publiccms.common.base.AbstractTemplateDirective 类,实现public void execute(RenderHandler handler) throwsIOException,Exception;方法,加上@Component注解并放在com.publiccms包(可以通过修改config.spring.ApplicationConfig的@ComponentScan注解增加或修改包名)中;就完成了一个指令的封装。

    示例:

package com.publiccms.views.directive.tools;

import java.io.IOException;

import com.publiccms.common.base.AbstractTemplateDirective;
import org.springframework.stereotype.Component;

import com.publiccms.common.handler.RenderHandler;

/**
 * 
 * MemoryDirective 技术框架版本指令
 *
 */
@Component
public class MemoryDirective extends AbstractTemplateDirective {

    @Override
    public void execute(RenderHandler handler) throws IOException, Exception {
        Runtime runtime = Runtime.getRuntime();
        handler.put("freeMemory", runtime.freeMemory());
        handler.put("totalMemory", runtime.totalMemory());
        handler.put("maxMemory", runtime.maxMemory());
        handler.render();
    }

}

    PublicCMS在启动过程中自动完成了指令的注册,指令名为类名去除Cms,Directive字符,然后首字母小写加下划线,调用示例:

<@_memory>
<p><label>总内存</label>:${totalMemory}</p>
<p><label>最大内存</label>:${maxMemory}</p>
<p><label>空闲内存</label>:${freeMemory}</p>
</@_memory>
或
<p><label>总内存</label>:<span class="total"></span></p>
<p><label>最大内存</label>:<span class="max"></span>}</p>
<p><label>空闲内存</label>:<span class="free"></span></p>
<script>
$.getJSON('//cms.publiccms.com/api/directive/memory', function(data){    
  $('.total').val(data.totalMemory);
  $('.max').val(data.maxMemory);
  $('.free').val(data.freeMemory);
});
</script>

    PublicCMS封装了模板指令数据别名的处理,别名的使用:

<@_memory;total,max,free>
<p><label>总内存</label>:${total}</p>
<p><label>最大内存</label>:${max}</p>
<p><label>空闲内存</label>:${free}</p>
</@_memory>

    PublicCMS的封装中还完成了对模板变量的回收,因此在指令结束后,是拿不到这些变量的,可以简单的理解为闭包原则;假如前文中有相同变量,也会还原这个变量;比如:

<!-- 此时不存在object这个变量 -->
<@_category id=1> <!-- _category指令根据输入参数id查询分类实体,并将结果导出为object -->
    <!-- 此时object这个变量代表id为1的分类实体 -->
    <@_content id=1>  <!-- _content指令根据输入参数id查询分类实体,并将结果导出为object -->
        <!-- 此时object这个变量代表id为1的内容实体 -->
    </@_content>
    <!-- 此时object这个变量代表id为1的分类实体 -->
</@_category>
<!-- 此时不存在object这个变量 -->

RenderHandler是对指令输入输出参数的操作封装。更多api可以查看源码或api文档

handler.getLong("id"),可以得到long类型的输入参数id;

handler.put("object", entity),可以将变量导出;

handler.render(),可以执行指令包含的模板内容的渲染,如果一个指令不执行render(),则指令包含的这些模板将不渲染,常见的使用场景:

<@_content id=-1> 这里的内容将不会输出和执行 </@_content>


    函数需要继承com.publiccms.common.base.BaseMethod类,实现public Object exec(@SuppressWarnings("rawtypes") List arguments) throws TemplateModelException方法,加上@Component注解并放在com.publiccms包。

    函数可以接收多个参数,被放置在arguments中,BaseMethod 中封装了对常见参数类型的取值方法,处理完数据后 直接返回即可。

    示例:

package com.publiccms.views.method.tools;

import java.util.List;

import org.springframework.stereotype.Component;

import com.publiccms.common.base.BaseMethod;
import com.publiccms.common.tools.CommonUtils;
import com.publiccms.common.tools.VerificationUtils;

import freemarker.template.TemplateModelException;

/**
 *
 * GetMd5Method
 * 
 */
@Component
public class GetMd5Method extends BaseMethod {

    @SuppressWarnings("unchecked")
    @Override
    public Object exec(@SuppressWarnings("rawtypes") List arguments) throws TemplateModelException {
        String string = getString(0, arguments);
        if (CommonUtils.notEmpty(string)) {
            return VerificationUtils.md5Encode(string);
        }
        return null;
    }
    
    @Override
    public boolean needAppToken() {
        return false;
    }

    @Override
    public int minParametersNumber() {
        return 1;
    }
}

    PublicCMS在启动过程中自动完成了函数的注册,函数名为类名去除Method字符,然后首字母小写,调用示例:

${getMd5("string")!}

    

保存页面 更多文档 数据结构 JAVA API

0条评论
发表评论