Beetl模板语言使用指南
Beetl是Bee Template language,Bee译为忙碌的人,意指忙碌中国的开发人员。目前版本0.6beta,大小约320K
Beetl是国人提供的一款开源免费得模板语言,作者有10余年Java开发经验,曾在国内外著名大公司工作过,根据自己实际使用模板语言的心得体会而编写的一款模板语言,它具有如下特性:
1 非常简单:它的语法是javascript一个子集,只有少量的大家熟悉的符号。任何了解java,或者javascript的人,都能快速学会。如果从未用过任何模板语言,用Beetl是非常很合适的
2 同时支持较为松散的MVC和严格的MVC,如果在模板语言里嵌入计算表达式,复杂条件表达式,以及函数调用有干涉业务逻辑嫌疑,你可以禁止使用这些语法。关于这一点,可以参考strictly enforces model-view separation
3 提供一系列其他模板语言没有提供的功能,如自定义占位符号,控制语句符号,虚拟属性,自定义函数,文本处理函数等,它们并不复杂,但有可能解决你在使用别的模板语言时候遇到的一些不便捷的问题
下载
作为模板语言,你可以用于任何适合在MVC的地方。如代码生成,或者web界面,
因为Beetl是基于antlr实现语法解析的,因此如果你仅仅对antlr感兴趣,beetl仍然可以作为你的一个重要参考
关于Beetl性能:
目前实现了runtime版本,适合代码生成。暂时不适合作为web界面。它本生的是以易读的方式实现,并未经过优化。然而,即将推出预编译版本,可以保证有很好的性能
Beetl目前渲染一个7K文件,内含少量控制语句和占位符,所需要时间是1毫秒,这是在我一个四年前的老机器上跑得,作为代码生成,你完全无需担心性能。
|
beetl(runtime,0.52)
|
Beetl(runtime,0.6)
|
Freemarker(2.3.1.8)
|
Beetl(compiled)
|
Velocity
|
7K(1000次)
|
4000毫秒
|
950毫秒
|
900毫秒
|
估计约400毫秒
|
|
展望Beetl预编译实现出来后,性能将至少提高2-3倍以上,因此未来能超越Freemaker
关于功能:
http://freemarker.sourceforge.net/fmVsVel.html 是一篇freemaker与velocity功能比较的文章,很幸运Beetl能以简单易学,更易扩展的方式支持所有功能。
下表是以此文章为基础做的比较
功能点
|
Beetl
|
Freemarker
|
velocity
|
Number and date support
|
yes
|
yes
|
no
|
Internationalization:
|
Yes,但不支持中文变量名
|
yes
|
no
|
Loop handling:
|
Yes,better
|
yes
|
no
|
Array handling on the template language level
|
yes
|
yes
|
no
|
Macros
|
Yes
|
Yes
|
no
|
Name-spaces:
|
No
|
yes
|
no
|
Java-independent string, list, and map manipulations with built-in functions/operators:
|
yes
|
yes
|
no
|
Expose typos and other mistakes in template
|
Yes,better
|
yes
|
no
|
Advanced rendering control:
|
yes
|
yes
|
no
|
Literals:
|
yes
|
yes
|
no
|
Advanced white-space removal
|
No ,不明白为啥有此需求
|
yes
|
no
|
Integration with other technologies:
|
yes
|
yes
|
yes
|
Powerful XML transformation capabilities:
|
no
|
yes
|
no
|
Advanced template metaprogramming:
|
No,不明白为啥有此需求
|
yes
|
no
|
function
|
No,觉得模板不需要
|
yes
|
No
|
自定义控制语句
|
yes
|
no
|
no
|
自定义占位符号
|
yes
|
no
|
no
|
严格MVC控制
|
yes
|
no
|
no
|
虚拟属性
|
yes
|
no
|
no
|
文本处理函数
|
yes
|
no
|
no
|
自定以错误处理Hanlder
|
yes
|
no
|
no
|
package org.bee.tl.samples;
import java.io.IOException;
import org.bee.tl.core.BeeTemplate;
public class HelloBeetl {
public static void main(String[] args)throws IOException {
Template template =new BeeTemplate("Hello,$name$");// 1
template.set("name","Beetl");//2
String result = template.getTextAsString();//3
System.out.println(result);
}
}
|
1用于BeeTemplate创建一个模板,此时使用的是一个字符串输入,输入也可以是java.io.File或者java.io.reader.对于beetl来说,如果输入是文件,那将会缓存中间的解析结果而大幅度提升性能
2定义变量,set方法允许字符串,对象作为参数,如果需要引用对象的属性,则用小数点,如$user.name$,如果属性是个List集合,可以用[索引],如$user.friends[0]$,如果属性是Map集合,
使用[key],key为任何对象,如$books[‘thinking in java’].author$
3调用template.getTextAsString() 或者template.getText(OutputStream os)都可以获得模板渲染的结果
Beetl默认情况下,采用#:作为控制语句开始,回车作为控制语句结束
#:for(user in userList){
hello,$user.name$
#:}
|
默认情况下,占位符号使用$作为开始和结尾占位符号
然而,Beetl支持自定义控制语句和占位符号,以适应不同类型模板文件
public static void main(String[] args) {
String input = ”…..”
BeeTemplate template =new BeeTemplate(input);
template.setStatementStart("<%");
template.setStatementEnd("%>");
template.setPlaceholderStart("~");
template.setPlaceholderStart("~");
template.getTextAsString();
}
|
此代码可以解析如下模板文件
<% var temp=”lijz”; %>
Hello ~temp~ !
|
建议:控制语句和占位符号最好不要影响原有文件,可以使用<!--: -->作为XML模板文件控制语句,使用#:作为通常shell脚本,配置文件的控制语句
Beetl 主要的接口Template 和 类 GroupTemplate.
Template 实现类分为BeeTemplate 和 CompiledBeeTemplate,前者用于解释执行模板,适合代码生成或者开发阶段使用,后者是预编译成class,适合web框架或者生产模式使用。
org.bee.tl.core.Template 常用API
|
public void set(String name, Object o)
|
设置模板变量
|
public void getText(OutputStream os)
|
渲染模板到os
|
public void getText(Writer w)
|
渲染模板到wirter
|
public String getTextAsString()
|
渲染模板,结果作为String返回
|
public void makeStrict(boolean isTrict)
|
是否使用严格MVC
|
org.bee.tl.core.Template 高级API (同org.bee.tl.core..GroupTemlate)
|
public void setPlaceholderStart(String placeholderStart)
|
设置占位符好开始标记,默认是$
|
public void setPlaceholderEnd(String placeholderEnd)
|
设置占位符好结束标记,默认是$
|
public void setStatementStart(String statementStart)
|
设置控制语句开始标记,默认是#:
|
public void setStatementEnd(String statementEnd) ;
|
设置控制语句结束标记,默认是null,也就是文件回车换行符号
|
public void registerFunction(String name,Function fn);
|
为Beetl注册一个自定义函数,参考高级用法
|
public void registerFormat(String name,Format format);
|
为Beetl创建一个格式化函数,参考高级用法
|
public void registerTextProcess(String name,TextPorcessFunction process);
|
为Beetl创建一个文本处理函数,参考高级用法
|
public void registerVirtualAttributeEval(VirtualAttributeEval e);
|
为某对象设置一个虚拟属性,参考高级用法
|
Beetl 不推荐直接调用高级API,在一个真正的系统里,首先通过GroupTemlate设置好模板所有属性,然后调用 GroupTemlate.getTetmplate来获取Template,如下代码
package org.bee.tl.samples;
import org.bee.tl.core.GroupTemplate;
public class GroupTemplateUtil {
static GroupTemplate group = new GroupTemplate();
static {|
group.setPlaceholderStart("$");
group.setPlaceholderEnd("$");
group.setStatementStart("#:");
group.setStatementEnd(null);
group.makeStrict(true);
}
public static GroupTemplate getGroup (){
return group;
}
|
org.bee.tl.core.GroupTemplate 常用API
|
public GroupTemplate()
|
构造一个GroupTemplate
|
public GroupTemplate(File root)
|
构造一个GroupTemplate,且制定模板文件跟目录,此目录下的模板文件都将编译成class,(前提是isProduct = true
|
public Template getStringTemplate(String input)
|
得到一个BeeTemplate
|
public Template getReaderTemplate(Reader reader)
|
得到一个BeeTemplate,输入是Reader
|
public Template getFileTemplate(String child)
|
如果isProudct=true,得到一个CompiledBeeTemplate模板,否则得到一个BeeTemplate
|
public void setProduct(boolean isProduct)
|
指示Beetl运行在开发模式还是生产模式
|
注意:要真正获得预编译支持以用于Web或者高性能项目, 只有通过GroupTemplate(File root) 构造的GroupTemplate ,且sProudct=true ,
然而,目前暂时不支持预编译版本
Beetl允许定义变量,准确的说,允许定义临时变量,如下所示
#:var name=’lijz’,loopCount=100+other ,girlName;
|
关键字var是必须得,这点不同于javascript
Beelt中得变量同javascript一样,有自己的作用域,如下模板输出为”lucy”
#:var name=’lijz’,i=1;
#:if(i>=1){
#:var name=’lucy’;
Hello,$name$
#:}
|
变量命名规则同javascript或者java,但不允许以俩个下划线开头"__",这是因为以此开头的多为Beetl内部的一些临时变量
Beetl支持类似javascript的算术表达式和条件表达式,如+ - * / % 以及(),如下例子
#:var a=1,b=2,c=3;
the result is $(a+b)*c-0.75$
|
Beetl支持类似Javascript,java的条件表达式 如>, <, == ,!=,>= , <= 以及 !,如下例子
#:var a=1,b=2,c=3;if((b-c)>=1){
Hello big!
#:}else{
:( ,small!
#:}
|
Beetl 支持for in 循环格式,以及break,continue,return (实际上可以出现在任何地方),如下例子
//java代码
tempalte.set("userList",userList);
//模板
总共 $userList.~size$
#:for(user in userList){
$user.~index$ . Welcome $user.name$!
#:}
|
如果循环中,需要引用当前索引和总数,可以分别使用虚拟属性index,size
Beetl只支持同javascript,java一样的if 语句,不支持switch. 如下例子
#:var isGirl = true;
#:if(isGir){
姑娘,你好
#:}else{
小伙子,你好
#:}
|
Beetl内置了少量实用函数,可以在Beetl任何地方调用,一般情况是在占位符里调用。
如下例子是调用NVL函数,判断如果变量为不为null,则输出变量,如果为null,则输出默认值
//java代码
template.set("name",service.getName(id));
//模板
The name is $nvl(name,"defaultValue")$
|
如下例子casef,判断变量与哪个值匹配,便显示响应的值
//java代码
template.set("score",3);
//模板
The name is $casef(score,3,"Good",2 ,"so-so",1 ,"bad","error score")$
|
Beetl允许用户自定义函数以适合特定领域使用,请参考高级用法。也欢迎有人把他认为能公用的函数发给我,我将作为核心函数放入beetl里
几乎所有的模板语言都支持格式化,Beetl也不列外,如下例子Beetl提供的内置日期格式
#:var date = now();
Today is $date,df="yyyy-MM-dd"$.
Today is $date,df$
|
如果没有为格式化函数输入参数,则使用默认值,df格式化函数默认值是local
Beetl允许用户自定义格式化函数以适合特定领域,请参考高级用户,也欢迎有人把他认为能公用的格式化函数发给我,我将作为核心函数放入beetl里
Beetl默认情况使用 org.bee.tl.core.DefaultErrorHandler 来处理语法解析错误和运行时刻的错误,默认情况下,会显示行号,错误原因,以及错误的关键字
如下所示
BeeTemplate t = new BeeTemplate("#:if(!isGirl){var c=1;}"); t.makeStrict(true); t.set("isGirl", false); t.getTextAsString() ;
会导致如下编译错误
STRICK_MVC 位于1行,符号 var 1|#:if(!isGirl){var c=1;}
|
对齐: 我发现别的模板语言要是做到对齐,非常困难,Beetl你完全不用担心,比如velocty,stringtemlate,freemarker例子都出现了不对齐的情况,影响了美观,Beetl完全无需担心输出对齐
包含其他模板文件:在Beetl中,这不是一个特殊的功能,通过调用函数includeFT,或者includeST都可以实现,前者是包含一个文件模板,后者是将一个string模板作为输入。详细使用请参考高级用法
Escape:可以使用/ 做escape符号,如hello,it's $money$/$, 或者Hello,it's $money+"/$"$
空值策略: 在输出一个变量的时候,如果为null,是应该抛出异常还是仅仅忽略,打印出默认值,Beetl相对于其他模板语言来说,控制的更为精细,如下代码
#:var NULL='N/A';var NULL_POLICY=1;
$u.name$
|
第一行指示空值情况下仅仅输出默认值,此时NULL_POLICY=1 表示不抛出异常,而仅仅输出默认值,0为默认情况,即抛出异常,停止渲染
你可以在Beetl中任何一处重新设置这些值以满足特定的需求。
文本处理函数:文本处理函数允许你将模板文件中的一段文件内容作为输入,经过函数操作,变成特定的输出,如下内置的replaceProperties
#:replaceProperties(ip,port){
Server_ip= 127.0.0.1
Server_port= 8080
#:}
#:if(isProduct) { delNext(){
Debug_para1=.....
Debug_para2=......
#:}
|
如果在java代码中,tempalte.set("ip",targetIP),template.set("port",targetPort);
则模板文件里等于号后的字符串将被以此替换.
如果在java代码中,template.set("isProduct",true),则所有debug参数都将被删除。关于文本处理函数概念,请参考高级用法
Beetl允许提供自定义函数以适合特定业务需求,自定义函数需要实现org.bee.tl.core.Function。如下定义了一个now函数仅仅返回一个java.util.Date实例
public class DateFunction implements Function {
public Object call(Object... paras) {
return new Date();
}
public static void main(String[] args) throws IOException{
GroupTemplate group = new GroupTemplate();
group.registerFunction("now", new DateFunction());
Template t = group.getStringTemplate("today is $now()$");
System.out.println(t.getTextAsString());
}
}
|
Beetl允许提供自定义格式化函数,用于格式化输出。 格式化函数需要实现org.bee.tl.core.Format
public class DateFormat extends Format {
public Object format(Object data,String pattern){
SimpleDateFormat sdf = null;
if(pattern==null){
sdf = new SimpleDateFormat();
}else{
sdf = new SimpleDateFormat(pattern);
}
return sdf.format(data);
}
public static void main(String[] args)throws IOException {
GroupTemplate group = new GroupTemplate();
group.registerFunction("now", new DateFunction());
group.registerFormat("df", new DateFormat());
Template t = group.getStringTemplate("today is $now(),df=’yyyy-MM-dd’$");
System.out.println(t.getTextAsString());
}
}
|
如果设置了严格MVC,则以下语法将不在模板文件里允许,否则将报出STRICK_MVC 错误
l 定义变量,为变量赋值
l 算术表达式
l 除了只允许布尔以外,不允许逻辑表达式
l 方法调用
无需为java对象定义额外的属性用于辅助显示,虚拟属性可以轻易做到,如Beetl为java.util.Collection 定义的一个虚拟属性size,用于表示集合大小
group.registerVirtualAttributeEval(new VirtualAttributeEval(){
public Object eval(Object o,String attributeName,Context ctx){
if(attributeName.equals("size")){
return ((Collection)o).size();
}else{
throw new IllegalArgumentException();
}
}
public boolean isSuppoert(Class c,String attributeName){
if(Collection.class.isAssignableFrom(c)&&attributeName.equals("size")){
return true;
}else{
return false;
}
}
});
|
这样,所以Collection子类都有虚拟属性size。$userList.~size$ 输出userList集合长度
实现虚拟属性,必须实现接口俩个方法,一个是isSupport,这让Beetl用于找到VirtualAttributeEval,eval方法用于计算虚拟属性
所谓文本处理函数,即允许处理模板文件里的一块内容。如下{}的内容在beetl运行的时候将会被删除
#:del(){
This content will be deleted
#:}
|
自定义文本处理函数必须实现org.bee.tl.core.TextPorcessFunction,需要实现requriedInput,用于告诉Beetl,是否需要先渲染文本体。
getOutput 用于返回文本处理函数的结果
如下是Beetl提供的内置的del文本处理函数实现
public class DeleteFunction extends TextPorcessFunction{
public String getOutput(){
return "";
}
@Override
public boolean requriedInput(){
return false;
}
}
|
可以通过父类属性args,获取输入参数,详细可以参考API
相关推荐
这个v0.6 beta1版本是由草哲进行汉化的,使得中国用户能够更方便地使用和理解其功能。WinSock,全称Windows Sockets,是Windows操作系统中的一个应用程序接口(API),用于支持TCP/IP协议,让开发者能够构建网络通信...
在实际使用"封包助手 V0.6 Beta Build 0306"时,开发者应根据自身项目的特性调整设置,同时密切注意软件的运行情况,及时向开发者报告任何遇到的问题,以帮助进一步完善这个工具。封包助手通过简化繁琐的打包步骤,...
WinSock Expert v0.6 beta1 运行于Win9x/2k/nt 作者:董雪强 email:dxqsoft@sina.com http://www.dxqsoft.com 一、版本历史 ……v0.6 beta1 调整了Filter的过滤功能,可以支持模糊的规则设置。 例如:可以使用FF...
标题 "dd for windows 0.6beta3" 提到的是一个专为Windows系统设计的版本,它是Linux下经典的`dd`工具的移植。这个工具在Linux世界中是用于数据复制、转换和备份的重要命令行工具,其功能强大且灵活。在Windows上,`...
Microsoft Windows Phone 7 Connector for Mac 0.6 Beta
"封包住手_v0.6_Beta_Build_0306"看起来是一个软件的版本标识,这可能是一个测试版的软件更新,其中"v0.6"代表版本号,"Beta"指的是测试阶段,"Build 0306"可能是构建日期或构建编号,表明这是2023年3月6日创建或...
这个版本是V0.6 beta 1,特别为中国用户进行了本地化,即“Cn”表示Chinese。在本文中,我们将深入探讨WinSock Expert的核心功能、工作原理以及如何使用它来提升你的网络管理和安全防护能力。 一、WinSock Expert的...
《微操触控之王0.6beta》是一款专为Android平台打造的纯代码游戏,其特色在于极小的安装容量,以及对玩家精准操控能力的极高要求。这款游戏摒弃了传统的音频和图像元素,完全依赖简洁的界面和精巧的逻辑设计来吸引...
中文版主要增加了中文语言包,修正为中式日历,对个别文件进行了汉化 模板遵循W3C规范,通过css 2.0和xhtml1.0支持语言包方式脏字过滤日志存档模块自定义...编辑,删除日志支持多类别可以使用BB CodeRSS聚合功能搜索评论
《PyExcelerator-0.6.4.1:Python中的Excel读写利器》 在Python编程环境中,处理Excel文件是一项常见的任务,PyExcelerator库正是为此而生。PyExcelerator-0.6.4.1是这个库的一个版本,它提供了高效且灵活的方式来...
1.增加处理 vmp3.5反调试 2.修复ThreadHideFromDebugger 参数处理bug 3.修复 win10 bypass objectcallback(PsProcessType & PsThreadType) 触发PG BSOD 4.增加处理 PEB_ProcessParameters 5.增加处理 ...
"WSockExpert V0.6 beta 网页抓包工具(汉化版)"是一款针对网页监控的专业工具,它能够帮助开发者轻松捕获并分析网页传输的数据,为编程和调试提供了强大的支持。本文将深入探讨这款工具的功能、工作原理以及其在实际...
SLAYER Leecher v0.6 是一个应用软件,专门设计用于下载和管理网络资源,尤其是对于种子(torrent)文件的处理。这个版本0.6的更新可能包含了性能优化、新功能添加或修复已知问题,以提升用户体验。在这款应用中,...
**xajax Plugin for Wordpress: 用于 Wordpress 的 xajax 插件与 xajax V0.6 beta 1** 在WordPress插件开发中,xajax Plugin for Wordpress 提供了一种功能强大的方式来实现AJAX(Asynchronous JavaScript and XML...
v0.6 Beta更新: 1.增加了Trackback功能(此前要求增加该功能的呼声很高) 2.增加mod_rewrite附加功能,SEO的很好手段 3.更改了RSS阅读方式 4.增加草稿功能 中文版主要增加了中文语言包,修正为中式日历...
SharpOD_x64_v0.6c_beta 0.6c版本好不容易搜到了,分享下。 里面有ollydbg版本的插件和x64dbg版本的插件。另外,插件只能在64位系统生效。 简要介绍: SharpOD v0.6c 更新日志 1.增加处理 vmp3.5反调试 2.修复...
使用 Charon 0.6 进行扫描时,用户需要根据实际情况配置扫描参数,比如选择扫描范围、指定目标代理服务器、设置扫描强度等。扫描完成后,Charon 0.6 会生成详细的报告,列出所有发现的问题和建议的解决方案。 在...