指令扩展绝对是一个比较好用的技能,那么该如何进行指令扩展呢?别着急,今天我们将一起学习指令扩展的小技巧。
1、逆向行驶,不按套路出牌
编写演示例子中使用到的HTML页面代码,本小节主要通过指令输出当前日期,具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jfinal模板引擎之二十</title>
</head>
<body>
今天的日期是:#now()
</body>
</html>
2、幕后黑手,竟然在此
使用指令是简单,幸福的一件事情。我们先来领略一番指令相关代码的魅力。因为Directive类类中代码不是很多,就直接阅读一下这边的源码,还是很有意思的。
package com.jfinal.template;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.stat.ast.Stat;
/**
* Directive 供用户继承并扩展自定义指令,具体用法可以参考
* com.jfinal.template.ext.directive 包下面的例子
*/
public abstract class Directive extends Stat {
/**
* 传递给指令的表达式列表
* 1:表达式列表可通过 exprList.eval(scope) 以及
*exprList.evalExprList(scope) 进行求值
* 2:使用赋值表达式可实现参数传递功能
*
* <pre>
* 例如:#render("_hot.html", title="热门新闻", list=newsList)
* </pre>
*/
protected ExprList exprList;
/**
* 具有 #end 结束符的指令内部嵌套的所有内容,
*调用 stat.exec(env, scope, writer)
* 即可执行指令内部嵌入所有指令与表达式,
*如果指令没有 #end 结束符,该属性无效
*/
protected Stat stat;
/**
* 指令被解析时注入指令参数表达式列表,
*继承类可以通过覆盖此方法对参数长度
* 和参数类型进行校验
*/
public void setExprList(ExprList exprList) {
this.exprList = exprList;
}
/**
* 指令被解析时注入指令 body 内容,
*仅对于具有 #end 结束符的指令有效
*/
public void setStat(Stat stat) {
this.stat = stat;
}
}
目测还有一层洋葱皮,需要你忍着眼泪拨下来。因为我们看到Directive继承自Stat,所以我们需要去Stat里一探究竟。请记住write方法,接下来我们会在程序中使用到它。
package com.jfinal.template.stat.ast;
import java.io.IOException;
import java.io.Writer;
import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.stat.Location;
import com.jfinal.template.stat.Scope;
/**
* Stat
*/
public abstract class Stat {
protected Location location;
public Stat setLocation(Location location) {
this.location = location;
return this;
}
public Location getLocation() {
return location;
}
public void setExprList(ExprList exprList) {
}
public void setStat(Stat stat) {
}
public abstract void exec(Env env, Scope scope, Writer writer);
public boolean hasEnd() {
return false;
}
protected void write(Writer writer, String str) {
try {
writer.write(str);
} catch (IOException e) {
throw new TemplateException(e.getMessage(), location, e);
}
}
protected void write(Writer writer, char[] chars) {
try {
writer.write(chars);
} catch (IOException e) {
throw new TemplateException(e.getMessage(), location, e);
}
}
}
3、刷卡上车,扩展指令
在第二小节,我们已经简单的看了指令相关的代码设计,那么作为使用者,该如何去自定义指令或者扩展指令呢?在例子中,我们先来创建一个普通的java类,然后继承Directive类。既然是抽象类,那么就得实现点什么。你懂的。
package com.demo.test;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.stat.Scope;
public class Now extends Directive{
@Override
public void exec(Env env, Scope scope, Writer writer) {
write(writer,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date()).toString());
}
}
4、验证代码,见证奇迹
测试效果很好,扩展指令已经成功引起了我们的注意。那么下面我们就来验证一下代码实现的效果是否正确,敬请期待。
呐,这就是你要的效果!是否感觉很炫酷!开玩笑,你以为这样,代码就能运行起来吗?你上当了,我们还必须在模板引擎中添加相关的配置。代码如下,假装你知道在jfinal的配置文件中设置。
public void configEngine(Engine me) {
//添加扩展指令
me.addDirective("now", new Now());
}
5、千里之行始于足下
本小节就讲这么多,敬请期待下节内容。更新时间不确定,哈哈~这个扩展指令有什么用?其实扩展指令的用途还是蛮多的,内置的指令有时候不能完全满足我们的生产需要,所以在实际情况中需要定制一些属于自己的指令。既然这样,那么我们扩展一下这个例子。
5.1页面代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jfinal模板引擎之二十</title>
</head>
<body>
今天的日期是:#now('2017-06-02 12:32:54')
</body>
</html>
5.2扩展指令代码
package com.demo.test;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.stat.Scope;
public class Now extends Directive{
@Override
public void exec(Env env, Scope scope, Writer writer) {
//获取参数
Expr my_date=exprList.getExpr(0);
//定义日期格式化规则
SimpleDateFormat sdf=new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf2=new
SimpleDateFormat("yyyy年MM月dd HH:mm:ss");
try {
//转换日期类型
Date date=sdf.parse(my_date.toString());
//输出格式化之后的结果
write(writer,sdf2.format(date).toString());
} catch (Exception e) {
//打印错误信息
e.printStackTrace();
}
}
}
网友评论