Beetl 自定义标签的使用笔记

最近写一个小博客网站用到模版引擎Beetl,  Beetl对自定义标签有很友好的支持;

使用自定义标签只需3步:

1)继承Tag类(或GeneralVarTagBinding类)实现render方法; 

2)注册标签:

 BeetlViewFactory.groupTemplate.registerTag("page", PageTag.class);
3)使用标签:

<#page  val="${pageData.page}">
……
</#page>


Tag类的源码:

public abstract class Tag
{
	protected Object[] args = null;
	protected GroupTemplate gt;
	protected Context ctx;
	protected ByteWriter bw;
	protected Statement bs;

	protected void doBodyRender()
	{

		bs.execute(ctx);

	}

	protected BodyContent getBodyContent()
	{
		ByteWriter writer = ctx.byteWriter;
		ByteWriter tempWriter = ctx.byteWriter.getTempWriter();
		ctx.byteWriter = tempWriter;
		doBodyRender();
		ctx.byteWriter = writer;
		return tempWriter.getTempConent();
	}

	public abstract void render();

	public void init(Context ctx, Object[] args, Statement st)
	{
		this.ctx = ctx;
		this.bw = ctx.byteWriter;
		this.gt = ctx.gt;
		this.args = args;
		this.bs = st;
	}

}

其中args参数第一个是标签名,即你自定义的标签名称 第二个是个Map保存了自定义标签的属性名,如:

分页标签<#page  val="${pageData.page}">,   args={'tage', Map[val=page]}

ctx是模版上下文,可以取全局变量:ctx.getGloabl("名字");


Beetl还有一个更友好的抽象类GeneralVarTagBinding,它提供一个getAttributeValue以属性名获取标签的属性值

GeneralVarTagBinding源码:

package org.beetl.core;

import java.util.Map;

/**
 * 此类子类将可以作为html 标签使用,除了能实现bindVars来初始化绑定的变量外,允许render方法里通过调用
 * 方法bing(name,value) 来绑定变量,如下是一个例子
 * <pre>
 * public class TestGeneralVarTagBinding extends GeneralVarTagBinding
{

	
	public void render()
	{
		for (int i = 0; i < 5; i++)
		{
			this.bind("value", i);
			this.doBodyRender();
		}

	}

}

  </pre>
  此例子会循环渲染标签体5次,并且每次循环都会设置value的值,如下是模板内容
  <pre>
 <#tag ; value>
	${value}
 </#tag>
 </pre>

 */
public abstract class GeneralVarTagBinding extends Tag implements TagVarBinding
{
	private Map<String, Integer> name2Index = null;

	@Override
	public Object[] bindVars()
	{
		// TODO Auto-generated method stub
		return null;
	}

	public void mapName2Index(Map<String, Integer> map)
	{
		name2Index = map;
	}

	public void bind(String name, Object value)
	{
		if (name2Index == null)
		{
			throw new RuntimeException();
		}
		Integer index = name2Index.get(name);
		if (index == null)
		{
			throw new RuntimeException();
		}
		ctx.vars[index] = value;
	}

	public Object getAttributeValue(String attrName)
	{
		Map map = (Map) this.args[1];
		return map.get(attrName);

	}

	public String getHtmlTagName()
	{
		return (String) this.args[0];
	}

}


下面是我写的分页标签的实现:

public class PageTag extends GeneralVarTagBinding {
    private  long total = 0;
    private  int perSize = 0;
    private int curNo = 0;
    private int pageNum = 0;
    private static final String SPAN = "span";
    private static final String A = "a";

    private void init(){
        Page page = (Page)getAttributeValue("val");
        total = page.getTotalNum();
        perSize = page.getPerSize();
        curNo = page.getCurNo();
        pageNum = (int)(total / perSize);
        if(pageNum * perSize < total){
            pageNum++;
        }
    }

    @Override
    public void render(){
        init();
        StringBuilder paging = new StringBuilder("");
        paging.append("<div class=\"pagination\">");
        if(curNo > 1){
            paging.append("<a class=\"firstPage\"> </a>")
                    .append("<a class=\"previousPage\"> </a>");
            if(curNo > 4){
                paging.append("<span class=\"pageBreak\">...</span>");
            }
            if(curNo - 2 > 0){
                paging.append("<a href=\"javascript:;\">").append(curNo - 2).append("</a>");
            }
            if(curNo - 1 > 0){
                paging.append("<a href=\"javascript:;\">").append(curNo - 1).append("</a>");
            }
        }else if(curNo == 1){
            paging.append("<span class=\"firstPage\"> </span>")
                    .append("<span class=\"previousPage\"> </span>");
        }
        paging.append("<span class=\"currentPage\">").append(curNo).append("</span>");
        if(curNo + 1 <= pageNum){
            paging.append("<a href=\"javascript:;\">").append(curNo + 1).append("</a>");
        }
        if(curNo + 2 <= pageNum){
            paging.append("<a href=\"javascript:;\">").append(curNo + 2).append("</a>");
        }
        if(pageNum - curNo > 2){
           paging.append("<span class=\"pageBreak\">...</span>");
        }
        if(curNo >= pageNum){
            paging.append("<span class=\"nextPage\" href=\"javascript:;\"> </span>")
                    .append("<span class=\"lastPage\" href=\"javascript:;\"> </span>");
        } else{
            paging.append("<a class=\"nextPage\" href=\"javascript:;\"> </a>")
                    .append("<a class=\"lastPage\" href=\"javascript:;\"> </a>");
        }
            paging.append("<span class=\"pageSkip\">")
                 .append("共").append(pageNum).append("页").append(total).append("条记录 到第<input id=\"pageNumber\" name=\"pageNumber\" value=\"1\" maxlength=\"9\" οnpaste=\"return false;\" />")
                 .append("页<button type=\"submit\"> </button>")
                 .append("</span></div>");
        try{
            ctx.byteWriter.writeString(paging.toString());
            this.doBodyRender();
            ctx.byteWriter.writeString(paging.toString());
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }
}
doBodyRender()方法是输出标签内的HTML

最终效果

更详细的使用文档可以去Beetl在线文档上看

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值