模板中可以通过模板标签和el表达式及函数用来获取动态数据,控制模板执行流程
在此文中我们介绍如何自定义模板标签和表达式函数

1.自定义标签

标签具有标签名、标签属性、标签体
标签可以控制呈现内容,执行流程
实现步骤
  • 实现扩展项(com.zving.framework.ui.zhtml.ZhtmlTagService)
  • 实现抽象方法
  • 定义标签属性,实现get\set方法
  • 实现流程方法
流程控制方法
I. doStartTag: 标签开始执行的时候调用,
返回值:
EVAL_BODY_INCLUDE-表示执行标签体(默认)
EVAL_BODY_BUFFERED-执行标签体,并将执行结果放在buffer缓存中
SKIP_BODY-跳过标签体
SKIP_PAGE-跳过页面
II.doAfterBody:标签体执行完成时调用,
返回值
EVAL_PAGE 执行标签后面的页面内容(默认)
EVAL_BODY_AGAIN 重新执行标签体
III.doEndTag:整个标签执行完成时调用
一般在此处获取buffer中的内容,对buffer进行处理
返回值
SKIP_PAGE
EVAL_PAGE(默认)
AbstractTag常用属性和方法
context:模板执行上下文
常用方法:
addDataVariable :添加一个变量数据,可以在标签体范围内使用el表达式和变量名获取到变量值
addRootVariable: 向模板执行上下文中添加一个变量,可以在页面范围内使用el表达式和变量名获取到变量值
getOut:返回当前的TemplateWriter实例,可以用该对象输出内容或获取缓存内容
eval: 执行一段表达式(一般为el表达式或变量名)
示例:
在该示例中实现了一个获取代码项数据的标签
1623137405814


图1. 创建扩展项

package com.zving.dynamic.tag;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import com.zving.dynamic.DynamicPlugin;
import com.zving.framework.collection.Mapx;
import com.zving.framework.template.AbstractTag;
import com.zving.framework.template.TagAttr;
import com.zving.framework.template.exception.TemplateRuntimeException;
import com.zving.framework.utility.StringUtil;
import com.zving.platform.util.CodeCache;
import com.zving.schema.ZDCode;
public class CodeDataTag extends AbstractTag {
protected String code;
protected String varCode;
protected String varList;
@Override
public String getDescription() {
return "代码项数据";
}
@Override
public String getExtendItemName() {
return "代码项数据";
}
@Override
public String getPluginID() {
return DynamicPlugin.ID;
}
@Override
public String getPrefix() {
return "z";
}
@Override
public List<TagAttr> getTagAttrs() {
List<TagAttr> list = new ArrayList<TagAttr>();
list.add(new TagAttr("code", true));
list.add(new TagAttr("varCode"));
list.add(new TagAttr("varList"));
return list;
}
@Override
public String getTagName() {
return "code";
}
@Override
public int doStartTag() throws TemplateRuntimeException {
if (StringUtil.isEmpty(varCode)) {
varCode = "CodeBean";
}
if (StringUtil.isEmpty(varList)) {
varList = "CodeList";
}
Mapx<String, ZDCode> map = CodeCache.getMapx(code);
ZDCode bean = map.remove("System");
List<ZDCode> list = new ArrayList<ZDCode>(map.size());
for (Entry<String, ZDCode> entry : map.entrySet()) {
list.add(entry.getValue());
}
Collections.sort(list, new Comparator<ZDCode>() {
@Override
public int compare(ZDCode o1, ZDCode o2) {
return new Long(o1.getCodeOrder()).compareTo(o2.getCodeOrder());
}
});
context.addDataVariable(varCode, bean);
context.addDataVariable(varList, list);
return EVAL_BODY_INCLUDE;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getVarCode() {
return varCode;
}
public void setVarCode(String varCode) {
this.varCode = varCode;
}
public String getVarList() {
return varList;
}
public void setVarList(String varList) {
this.varList = varList;
}
}
代码1. 实现Tag类,实现标签逻辑

<z:code code="Theme" varCode="bean" varList="codelist">
<select name="ContentStatusList">
<option value="">请选择</option>
<z:foreach data="${codelist}">
<option value="${value.CodeValue}">${value.CodeName}</option>
</z:foreach>
</select>
</z:code>
代码2. 标签使用测试,获取主题代码项列表,并以下拉选择框的方式显示
1623139291156


图2. 页面执行呈现结果

2.自定义页面函数

函数具有方法名、参数列表、返回值
实现步骤
  • 实现扩展项(扩展服务ID:com.zving.framework.ui.zhtml.ZhtmlFunctionService)
  • 实现接口(com.zving.framework.expression.IFunction)或者 继承(com.zving.framework.expression.AbstractFunction)
  • 定义参数类型
  • 实现函数方法得到返回值
示例:
该示例中实现了输出模糊处理后的手机号、用户名、邮箱的表达式函数
1623137553804


图3.添加扩展项
package com.zving.dynamic.function;
import com.zving.common.util.StringHelper;
import com.zving.framework.expression.AbstractFunction;
import com.zving.framework.expression.ExpressionException;
import com.zving.framework.expression.IFunction;
import com.zving.framework.expression.IVariableResolver;
/**
* 文本模糊函数,用来遮挡手机号,邮箱,账户名等
*/
public class Mosaics extends AbstractFunction implements IFunction {
@Override
public Object execute(IVariableResolver arg0, Object... args) throws ExpressionException {
String value = (String) args[0];
int len = value.length();
int index = value.indexOf('@');
if (index > 0) {
String front = value.substring(0, index);
int mosLen = 0;
int frontLen = front.length();
if (frontLen > 3) {
mosLen = frontLen - 2;
front = front.charAt(0) + StringHelper.repeatText('*', mosLen) + front.charAt(frontLen - 1);
} else if (frontLen > 1) {
mosLen = frontLen - 1;
front = front.charAt(0) + StringHelper.repeatText('*', mosLen);
}
int mIndex = value.indexOf('.', index);
String middle = value.substring(index + 1, mIndex);
int middleLen = middle.length();
if (mosLen < 2) {
middle = StringHelper.repeatText('*', middleLen);
mosLen = mosLen + middleLen;
}
String end = value.substring(mIndex);
StringBuilder sb = new StringBuilder(len);
value = sb.append(front).append('@').append(middle).append(end).toString();
return value;
} else {
if (len > 11) {
value = value.substring(0, 3) + StringHelper.repeatText('*', len - 6) + value.substring(len - 3);
} else if (len > 6) {
value = value.substring(0, 2) + StringHelper.repeatText('*', len - 4) + value.substring(len - 2);
} else if (len > 3) {
value = value.substring(0, 1) + StringHelper.repeatText('*', len - 2) + value.substring(len - 1);
} else if (len > 1) {
value = value.charAt(1) + StringHelper.repeatText('*', len - 1);
}
}
return value;
}
@Override
public Class<?>[] getArgumentTypes() {
return new Class<?>[] { Object.class };
}
@Override
public String getFunctionName() {
return "mosa";
}
@Override
public String getFunctionPrefix() {
return "";
}
}
代码3. 实现Function类

手机号:${mosa('13800000000')}
<hr>
邮箱:${mosa('myemail@qq.com')}
<hr>
用户名:${mosa('myname')}
代码4. 测试页面代码
1623139338289


图4. 访问测试页面执行结果