首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

制作一个自己的模板引擎(四)

2013-03-06 
打造一个自己的模板引擎(四)接下来我们要写几个扩展标签,使其支持动态include.在前面我们的编译器会支持静

打造一个自己的模板引擎(四)
接下来我们要写几个扩展标签,使其支持动态include.
在前面我们的编译器会支持静态include,静态包含是把要包含的文件在编译期就包含进来一起编译。
动态包含是在运行期调用模板引擎编译并执行一个模板,然后把结果包含进来。
如果纯粹是包含一个文件,那么从结果上看动态包含和静态包含没有任何区别,我们要支持的这个动态包含是类似于struts2中的<s:action>标签
不但能够动态的包含一个文件,而且能在包含之前执行某一个类的某一个方法,然后再调用模板引擎把模板进行渲染。
这样做的一个好处是主页面只是一个框架,不包含任何数据或者只包含很少的数据,然后页面的每一个部分通过调用不用的标签来完成渲染。
这样可以使页面上的逻辑尽可能的分离,比如某一块数据可能被很多页面引用,这样分离之后可以把每一块都做成一个组件,不同的页面进行不同的组合。
先来定义一下标签的结构:
<t:action className="test.mytest.HelloAction" method="execute" page="/template/hello.html">
    <t:param name="var1" value="test1"/>
</t:action>
当这个标签执行的时候会先调用HelloAction, 然后再调用模板引擎渲染hello.html。数据通过pageContext进行传递。


我们需要定义两个标签,一个是ActionTag, 一个是ParameterTag, 先看代码:

public class ActionTag extends TagSupport implements com.skin.ayada.tagext.ParameterTag{    private String className;    private String method;    private String page;    private Parameters parameters = new Parameters();    @Override    public int doStartTag(){        super.doStartTag();        this.parameters.clear();        return TagSupport.EVAL_PAGE;    }    @Override    public int doEndTag(){        Map<String, Object> context = null;        if(this.className != null)        {            // 调用指定的类的某个方法, 这个方法返回渲染页面需要用到的数据            context = ActionDispatcher.dispatch(pageContext, this.parameters, this.className, this.method);        }        if(this.getPage() != null)        {            // 调用模板引擎进行渲染            // 此处不使用当前的pageContext, 模板引擎在渲染一个新的页面的时候会创建一个新的PageContext            // 这样是为了做到数据隔离            TemplateManager.execute(this.getPage(), context, pageContext.getOut());        }        return TagSupport.EVAL_PAGE;    }    @Override    public void setParameter(String name, Object value){        parameters.setParameter(name, value);    }    // getter & setter    ...}public class ParameterTag extends BodyTagSupport{    private String name;    private String value;    @Override    public int doEndTag()    {        Tag parent = this.getParent();        if(parent instanceof com.skin.ayada.tagext.ParameterTag)        {            String value = this.getValue();            if(value == null)            {                BodyContent body = this.getBodyContent();                value = (body != null ? body.getString() : null);            }            com.skin.ayada.tagext.ParameterTag tag = (com.skin.ayada.tagext.ParameterTag)(parent);            tag.setParameter(this.getName(), value);            return TagSupport.EVAL_PAGE;        }        else        {            throw new RuntimeException("Illegal use of parameter-style tag without servlet as its direct parent");        }    }    // getter & setter    ...}

完整的工程源码: http://ayada.googlecode.com/svn/trunk/
也可以发邮件给我索取: xuesong.net@163.com

热点排行