Enjoy使用自定义首定界符'#'换'$' , 这个功能,在很多模板工具到也有。不过自定义定界符会带来太多使用负担,弊大于利了。但是有些业务确实要用的话,单独 new Engine() 一个不和内置的 Engine 混合,应该也没问题。毕竟再加一个其他模板引擎的话,也是两个写法了差异更大。。。
算了废话不多说了,上码:
还是使用 JFinal 官网 demo 入手:
1、在项目中建一个 包目录:
com.jfinal.template
2、把JF 源码 EngineConfig.java 拷贝过来,加一个参数 lexerStartDelimiter :
private char lexerStartDelimiter = '#'; /** * 设置模板语法指令 起始字符,默认为 # */ public void setLexerStartDelimiter(char lexerStartDelimiter) { this.lexerStartDelimiter = lexerStartDelimiter; } public char getLexerStartDelimiter() { return lexerStartDelimiter; }
后续再把全部 修改源码贴上来,这里方便阅读操作流程。
3、再创建一个包 stat 如上截图所示:
com.jfinal.template.stat
4、把JF 源码 Lexer.java拷贝过来,加一个参数 startDelimiter:
char startDelimiter; public Lexer(StringBuilder content, String fileName, Set<String> keepLineBlankDirectives, char startDelimiter) { this.keepLineBlankDirectives = keepLineBlankDirectives; int len = content.length(); buf = new char[len + 1]; content.getChars(0, content.length(), buf, 0); buf[len] = EOF; this.fileName = fileName; this.startDelimiter = startDelimiter; }
用快捷键 把源码中的 '#' 换成 startDelimiter 变量。
5、把 JF 源码 Parser.java 拷贝过来,再给 new Lexer 加个参数 ec.getLexerStartDelimiter() 自定义的 定界符 变量:
public StatList parse() { EngineConfig ec = env.getEngineConfig(); tokenList = new Lexer(content, fileName, ec.getKeepLineBlankDirectives(), ec.getLexerStartDelimiter()).scan(); tokenList.add(EOF); StatList statList = statList(); if (peek() != EOF) { throw new ParseException("Syntax error: can not match \"#" + peek().value() + "\"", getLocation(peek().row)); } return statList; }
6、修改项目的部署启动脚本 jfinal.sh Windows 的 jfinal.bat 类似处理。
CP=${APP_BASE_PATH}/lib/你项目打包出来的名字.jar:${APP_BASE_PATH}/config:${APP_BASE_PATH}/lib/*
原理就是 让 jvm 先加载 你改造的 jar,里面有上面改的三个 JF 源码类,后加载 JF 时,这三个类已经占位了。
如果是Tomcat 项目,那么就不用处理了,它会自动先加载 classes目录的。
好了,上测试:
为了方便,还是使用 IndexController :
@Path(value = "/", viewPath = "/index") public class IndexController extends Controller { public void index() { Engine en = new Engine(); en.getEngineConfig().setLexerStartDelimiter('$'); String v = en.getTemplateByString("$(a) $if(a) OK $end").renderToString(Kv.by("a", "A")); set("v", v); render("index.html"); } }
#@layout() #define main() <h1>--#(v)--</h1> <div class="table_box"> <p>欢迎来到 JFinal极速开发世界!</p> <br><br><br>
上面设置是:
en.getEngineConfig().setLexerStartDelimiter('$');
需要自定义定界字符的功能 就new Engine()一个对象,单独放在自己业务里面,经常调用的话,就用 静态变量声明一下,和普通使用是一样的。
开发启动,idea 会自动先加载 编译目录的:
------------------------------------------------
源码贴不上了。。。内容应该是太多了,不过改的代码也没几行,自己操作也行。
https://gitee.com/jfinal/jfinal/tree/master/src/main/java/com/jfinal/template
不建议这样使用!!!除非没办法,比引入多个模板引擎强一点。
PS:未深度测试,需要自己多试用,如果遇到问题,需要改源码,和上面类似处理就行。也欢迎反馈到这个帖子下面,大家如果用到这个功能,也可以避免误踩坑。。。
好了,分享结束!祝元旦快乐~