指令擴(kuò)展絕對(duì)是一個(gè)比較好用的技能囱淋,那么該如何進(jìn)行指令擴(kuò)展呢?別著急餐塘,今天我們將一起學(xué)習(xí)指令擴(kuò)展的小技巧妥衣。
1、逆向行駛,不按套路出牌
編寫(xiě)演示例子中使用到的HTML頁(yè)面代碼税手,本小節(jié)主要通過(guò)指令輸出當(dāng)前日期蜂筹,具體代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jfinal模板引擎之二十</title>
</head>
<body>
今天的日期是:#now()
</body>
</html>
2、幕后黑手芦倒,竟然在此
使用指令是簡(jiǎn)單艺挪,幸福的一件事情。我們先來(lái)領(lǐng)略一番指令相關(guān)代碼的魅力兵扬。因?yàn)镈irective類類中代碼不是很多麻裳,就直接閱讀一下這邊的源碼,還是很有意思的器钟。
package com.jfinal.template;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.stat.ast.Stat;
/**
* Directive 供用戶繼承并擴(kuò)展自定義指令津坑,具體用法可以參考
* com.jfinal.template.ext.directive 包下面的例子
*/
public abstract class Directive extends Stat {
/**
* 傳遞給指令的表達(dá)式列表
* 1:表達(dá)式列表可通過(guò) exprList.eval(scope) 以及
*exprList.evalExprList(scope) 進(jìn)行求值
* 2:使用賦值表達(dá)式可實(shí)現(xiàn)參數(shù)傳遞功能
*
* <pre>
* 例如:#render("_hot.html", title="熱門新聞", list=newsList)
* </pre>
*/
protected ExprList exprList;
/**
* 具有 #end 結(jié)束符的指令內(nèi)部嵌套的所有內(nèi)容,
*調(diào)用 stat.exec(env, scope, writer)
* 即可執(zhí)行指令內(nèi)部嵌入所有指令與表達(dá)式傲霸,
*如果指令沒(méi)有 #end 結(jié)束符疆瑰,該屬性無(wú)效
*/
protected Stat stat;
/**
* 指令被解析時(shí)注入指令參數(shù)表達(dá)式列表,
*繼承類可以通過(guò)覆蓋此方法對(duì)參數(shù)長(zhǎng)度
* 和參數(shù)類型進(jìn)行校驗(yàn)
*/
public void setExprList(ExprList exprList) {
this.exprList = exprList;
}
/**
* 指令被解析時(shí)注入指令 body 內(nèi)容狞谱,
*僅對(duì)于具有 #end 結(jié)束符的指令有效
*/
public void setStat(Stat stat) {
this.stat = stat;
}
}
目測(cè)還有一層洋蔥皮乃摹,需要你忍著眼淚撥下來(lái)。因?yàn)槲覀兛吹紻irective繼承自Stat跟衅,所以我們需要去Stat里一探究竟孵睬。請(qǐng)記住write方法,接下來(lái)我們會(huì)在程序中使用到它伶跷。
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掰读、刷卡上車,擴(kuò)展指令
在第二小節(jié)叭莫,我們已經(jīng)簡(jiǎn)單的看了指令相關(guān)的代碼設(shè)計(jì)蹈集,那么作為使用者,該如何去自定義指令或者擴(kuò)展指令呢雇初?在例子中拢肆,我們先來(lái)創(chuàng)建一個(gè)普通的java類,然后繼承Directive類靖诗。既然是抽象類郭怪,那么就得實(shí)現(xiàn)點(diǎn)什么。你懂的刊橘。
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鄙才、驗(yàn)證代碼,見(jiàn)證奇跡
很好促绵,擴(kuò)展指令已經(jīng)成功引起了我們的注意攒庵。那么下面我們就來(lái)驗(yàn)證一下代碼實(shí)現(xiàn)的效果是否正確嘴纺,敬請(qǐng)期待。
吶浓冒,這就是你要的效果栽渴!是否感覺(jué)很炫酷!開(kāi)玩笑裆蒸,你以為這樣熔萧,代碼就能運(yùn)行起來(lái)嗎?你上當(dāng)了僚祷,我們還必須在模板引擎中添加相關(guān)的配置。代碼如下贮缕,假裝你知道在jfinal的配置文件中設(shè)置辙谜。
public void configEngine(Engine me) {
//添加擴(kuò)展指令
me.addDirective("now", new Now());
}
5、千里之行始于足下
本小節(jié)就講這么多感昼,敬請(qǐng)期待下節(jié)內(nèi)容装哆。更新時(shí)間不確定,哈哈~這個(gè)擴(kuò)展指令有什么用定嗓?其實(shí)擴(kuò)展指令的用途還是蠻多的蜕琴,內(nèi)置的指令有時(shí)候不能完全滿足我們的生產(chǎn)需要,所以在實(shí)際情況中需要定制一些屬于自己的指令宵溅。既然這樣凌简,那么我們擴(kuò)展一下這個(gè)例子。
5.1頁(yè)面代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jfinal模板引擎之二十</title>
</head>
<body>
今天的日期是:#now('2017-06-02 12:32:54')
</body>
</html>
5.2擴(kuò)展指令代碼
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) {
//獲取參數(shù)
Expr my_date=exprList.getExpr(0);
//定義日期格式化規(guī)則
SimpleDateFormat sdf=new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf2=new
SimpleDateFormat("yyyy年MM月dd HH:mm:ss");
try {
//轉(zhuǎn)換日期類型
Date date=sdf.parse(my_date.toString());
//輸出格式化之后的結(jié)果
write(writer,sdf2.format(date).toString());
} catch (Exception e) {
//打印錯(cuò)誤信息
e.printStackTrace();
}
}
}