最近写一个小博客网站用到模版引擎Beetl
http://www.ibeetl.com, 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\" onpaste=\"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在线文档上看
http://ibeetl.com/guide/#_%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E7%AD%BE
- 大小: 17.8 KB
分享到:
相关推荐
1.2 使用标签文件 除了简单的标签机制,还可以通过标签文件实现更复杂的逻辑。标签文件是一个JSP片段,包含在自定义标签中,当标签被解析时,它的内容会被插入到JSP页面相应的位置。 二、自定义标签简介 2.1 自定义...
### 自定义标签学习笔记 #### 一、什么是自定义标签? 自定义标签是JSP(Java Server Pages)中的一种功能,允许开发者创建可重用的组件。这些组件封装了特定的功能,可以在不同的JSP页面中复用,从而提高开发效率...
本文将基于一篇技术笔记——《自定义标签库制作(二)》,详细阐述如何创建并应用带有参数的自定义标签。 **一、自定义标签的概念与意义** 自定义标签允许开发者封装复杂的业务逻辑和UI组件,以标签的形式在JSP...
在IT行业中,自定义标签是一种常见的组织和管理信息的方式,特别是在文档、文件、笔记或数据库系统中。自定义标签允许用户根据个人需求创建特定的分类标准,以更灵活地整理和检索信息。以下是对这个主题的详细解释:...
首先,自定义标签(Customized Tags)是一种允许用户创建和管理他们自己的标签的方式,常见于笔记应用、项目管理工具等。实现自定义标签通常涉及以下几个步骤: 1. 创建输入框:用户可以在这里输入新的标签。 2. ...
Inno自定义界面学习笔记第四部分专注于自定义按钮的实现,这涉及到对Inno Setup脚本语言的理解以及利用其API来添加交互元素。本资源包包含了实现自定义按钮所需的所有关键组件,包括脚本文件(UITest.iss)、图片...
图文,自定义标签都可以.zip"项目提供的JYLabelsSelect库是一个强大的工具,它简化了自适应标签控件的实现,支持图文混排和动态管理,同时允许高度的定制化,是iOS开发者进行界面设计时值得参考和使用的资源。
NIOS II自定义指令学习笔记主要探讨了如何通过自定义指令来扩展NIOS II处理器的功能。这种能力使得开发者能够根据特定的应用需求,向处理器指令集中增加特定功能的指令,从而提高程序运行效率。 #### 二、自定义...
1. **按键位置自定义**:用户可以根据自己的使用习惯,调整键盘上各个按键的位置。比如,如果你经常需要使用某些不常用的按键,可以将它们移动到更便于触及的地方。 2. **按键效果自定义**:除了位置,用户还可以...
zabbix 4.0 自带键值创建自定义模板详细笔记文档总结 zabbix 是一个功能强大的监控软件,提供了多种监控方式,包括被动式和主动式。本文将详细介绍 zabbix 4.0 中的自带键值创建自定义模板,并提供了多个监控项和...
小程序自定义组件笔记总结
本篇学习笔记将深入探讨如何自定义ProgressBar的样式。 首先,我们了解下ProgressBar的基本类型。Android提供了几种内置的样式,如Horizontal(水平)、Circular(圆形)和Indeterminate(不确定进度)。Horizontal...
在Zabbix 4.0版本中,自定义脚本键值和自定义模板监控是两个强大的功能,它们极大地扩展了Zabbix监控的能力,使用户能够根据特定需求定制监控策略。 首先,我们来探讨自定义脚本键值。在Zabbix中,自定义脚本允许...
10. **测试与调试**:确保在不同设备和Android版本上测试自定义View的行为,使用Android Studio的Layout Inspector查看View的布局信息,以及使用Hierarchy Viewer(Android Studio 3.0以下版本)或Layout Validation...
这篇学习笔记将深入探讨如何在iOS应用中实现自定义导航栏以及如何有效利用表格展示数据。 首先,自定义导航栏允许开发者根据应用程序的品牌风格或功能需求进行个性化设计。在iOS中,我们通常使用...
BeetlSQL是一个高效的数据访问框架,旨在提升开发效率,降低维护成本,并提供跨数据库平台的支持。它设计的核心思想是以SQL为中心,强调SQL在...通过使用BeetlSQL,开发者可以更专注于业务逻辑,而非数据库操作的细节。
通过`源码`和`工具`这两个标签,我们可以推断这篇博客可能包含了实际的代码示例和可能使用的辅助工具或技巧,比如调试工具、性能分析工具等。遗憾的是,由于没有具体的压缩包文件内容,无法进一步深入讨论这些实例...
### MicroPython自定义模块添加(使用C语言实现) 在深入探讨如何通过C语言为MicroPython添加自定义模块之前,我们先来理解一下整个过程的基本框架和步骤。本篇笔记主要聚焦于利用C语言来扩展MicroPython的功能,并...
定制您自己的快捷键,使您使用电脑时更方便快捷