Beetl( 发音同Beetle )相对于其他java模板引擎,具有功能齐全,语法直观,性能超高,以及编写的模板容易维护等特点。使得开发和维护模板有很好的体验。同时,Beetl具备引擎可定制性,可以打造自己的模板引擎。总得来说,它的特性如下:
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.10.0.RELEASE</version>
</dependency>
提示:为方便管理,我们一般把模板内容放在一个文件里,使用时读取该文件即可
<% for(user in list){ %>
hello ${user.name}
<% } %>
提示:Beetl对模板文件的后缀名没啥要求,只要保证读出来是正常的文本内容即可。即:我们创建出来(用来放置模板内容的)模板文件的后缀名自取即可,可以是.txt、.html、.js、.sh、.abc之类的都行。
Beetl
的核心是GroupTemplate
,是一个重量级对象,实际使用的时候建议使用单模式创建,创建GroupTemplate
需要2个参数,一个是模板资源加载器,一个是配置类,模板资源加载器Beetl
内置了6种。
方式一:StringTemplateResourceLoader
:字符串模板加载器,用于加载字符串模板
//初始化代码
StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();
Configuration cfg = Configuration.defaultConfiguration();
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
//获取模板(参数即为模板内容)
Template t = gt.getTemplate("hello,${name}");
t.binding("name", "beetl");
/*
* 渲染结果
* template.render() 返回渲染结果
* template.renderTo(Writer) 渲染结果输出到Writer里,如果你的Writer是一个FilterWriter,则可把输出保存到文件里
* template.renderTo(OutputStream) 渲染结果输出到OutputStream里
*/
String str = t.render();
System.out.println(str);
方式二:FileResourceLoader
:文件模板加载器,需要一个根目录作为参数构造,传入getTemplate
方法的String
是模板文件相对于Root
目录的相对路径
String root = System.getProperty("user.dir")+File.separator+"template";
FileResourceLoader resourceLoader = new FileResourceLoader(root,"utf-8");
Configuration cfg = Configuration.defaultConfiguration();
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
// 从指定文件中加载模板
Template t = gt.getTemplate("/s01/hello.txt");
/*
* 渲染结果
* template.render() 返回渲染结果
* template.renderTo(Writer) 渲染结果输出到Writer里,如果你的Writer是一个FilterWriter,则可把输出保存到文件里
* template.renderTo(OutputStream) 渲染结果输出到OutputStream里
*/
String str = t.render();
System.out.println(str);
方式三:ClasspathResourceLoader
:现代web
应用最常用的文件模板加载器,模板文件位于Classpath
里
/*
* new ClasspathResourceLoader("org/beetl/sample/s01/"):指定org/beetl/sample/s01/的为模板文件的根目录
* new ClasspathResourceLoader("template/"):指定template/的为模板文件的根目录
* new ClasspathResourceLoader():默认即classpath的根目录就为模板文件的根目录
*/
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("org/beetl/sample/s01/");
Configuration cfg = Configuration.defaultConfiguration();
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
// 从指定文件中加载模板
Template t = gt.getTemplate("/hello.txt");
/*
* 渲染结果
* template.render() 返回渲染结果
* template.renderTo(Writer) 渲染结果输出到Writer里,如果你的Writer是一个FilterWriter,则可把输出保存到文件里
* template.renderTo(OutputStream) 渲染结果输出到OutputStream里
*/
String str = t.render();
System.out.println(str);
方式四:WebAppResourceLoader
:用于webapp
集成,假定模板根目录就是WebRoot
目录。
使用相对较少,这里不多作说明
方式五:MapResourceLoader
:可以动态存入模板
使用相对较少,这里不多作说明
方式六:CompositeResourceLoader
:混合使用多种加载方式
使用相对较少,这里不多作说明
我们在构造GroupTemplate
时,需要传入对应的配置,这里对配置进行简单说明
#默认配置
# 模板引擎
ENGINE=org.beetl.core.engine.FastRutimeEngine
# 占位符 开始、结束标志
DELIMITER_PLACEHOLDER_START=${
DELIMITER_PLACEHOLDER_END=}
# 语句块 开始、结束标志
DELIMITER_STATEMENT_START=<%
DELIMITER_STATEMENT_END=%>
# 渲染结果直接输出为字节
DIRECT_BYTE_OUTPUT = FALSE
HTML_TAG_SUPPORT = true
HTML_TAG_FLAG = #
HTML_TAG_BINDING_ATTRIBUTE = var
NATIVE_CALL = TRUE
# 模板字符集
TEMPLATE_CHARSET = UTF-8
ERROR_HANDLER = org.beetl.core.ConsoleErrorHandler
NATIVE_SECUARTY_MANAGER= org.beetl.core.DefaultNativeSecurityManager
MVC_STRICT = FALSE
#资源配置,resource后的属性只限于特定ResourceLoader
RESOURCE_LOADER=org.beetl.core.resource.ClasspathResourceLoader
#classpath 根路径
RESOURCE.root= /
#是否检测文件变化,开发用true合适,但线上要改为false
RESOURCE.autoCheck= true
#自定义脚本方法文件的Root目录和后缀
RESOURCE.functionRoot = functions
RESOURCE.functionSuffix = html
#自定义标签文件Root目录和后缀
RESOURCE.tagRoot = htmltag
RESOURCE.tagSuffix = tag
##### 扩展 ##############
## 内置的方法
FN.date = org.beetl.ext.fn.DateFunction
......
##内置的功能包
FNP.strutil = org.beetl.ext.fn.StringUtil
......
##内置的默认格式化函数
FTC.java.util.Date = org.beetl.ext.format.DateFormat
.....
## 标签类
TAG.include= org.beetl.ext.tag.IncludeTag
TAG.html.include= org.beetl.ext.tag.html.IncludeResourceHtmlTag
TAG.html.foreach= org.beetl.ext.tag.html.ForeachHtmlTag
注:Configuration.defaultConfiguration();
方法加载的是位于/org/beetl/core/beetl-default.properties
里的默认配置;一般的,我们使用默认配置即可。
- **定界符:**圈定一个范围,在这个范围内可以编写多个beetl语法。默认以
<%
开始,以%>
结束。- 占位符: 主要用于把变量/常量进行输出。
注:如果表达式跟定界符或者占位符有冲突,可以在用""符号
示例:
<%
var a = 2;
var b = 3;
var result = a+b;
%>
hello 2+3=${result}
注:如果在定界符范围内需要对变量取值,那么直接使用该变量即可,无需使用占位符,如:
<%
var a = "hi";
var c = a + "beetl"; //不要使用var c = ${a} + "beetl"这种错误写法
%>
<% /* %>
这里的内容,将不会被Beetl解析,同时(这部分内容也不会出现在)渲染后的输出结果里
<% */ %>
临时变量: 在模板中定义的变量成为临时变量,这类似js
中采用var
定义变量
<%
var a = 3;
var b = 3,c = "abc",d=true,e=null;
var f = [1,2,3];
var g = {key1:a,key2:c};
var i = a+b;
%>
**全局变量: ** 全局变量是通过在java
代码里调用template.binding
传入的变量,这些变量能在模板的任何一个地方,包括子模板都能访问到
template.binding("list",service.getUserList());
//在模板里
<%
for(user in list){
%>
hello,${user.name};
<% } %>
注:自从2.8.0版本后,有一个特殊的变量成为root变量,当模板找不到变量的时候,会寻找root变量的属性来作为变量的值,这个root变量必须绑定为"_root"
template.binding("_root",new User());
//在模板里,俩个都一样
${name}
${wife.name}
共享变量: 共享变量指在所有模板中都可以引用的变量,可通过groupTemplate.setSharedVars(Map<String, Object> sharedVars)
传入变量,这些变量能用在所有模板的任何一个地方引用到
//.....
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
// 设置共享变量
Map<String,Object> shared = new HashMap<String,Object>();
shared.put("name", "beetl");
gt.setSharedVars(shared);
Template t = gt.getTemplate("/org/beetl/sample/s0208/t1.txt");
String str = t.render();
System.out.println(str);
t = gt.getTemplate("/org/beetl/sample/s0208/t2.txt");
str = t.render();
System.out.println(str);
模板变量: 模板变量是一种特殊的变量,即可以将模板中任何一段的输出赋值到该变量,并允许稍后在其他地方使用
<%
var content = {
var c = "1234";
print(c);
%>
模板其他内容:
<% }; %>
注:模板变量是局部变量的一种拓展,类似于java中的共用方法逻辑抽取。
属性引用(示例说明)
${name}
${user.name}
${userList[0]}
${map["name"]}
${userList.~size}
,~
加上虚拟属性名,size是Beetl
对数组/集合默认内置的虚拟属性属性赋值(示例说明)
<%
var user = ....
user.name="joelli";
user.friends[0] = getNewUser();
user.map["name"] = "joelli";
%>
Beetl
支持类似javascript
的算术表达式和条件表达式,如+
、-
、*
、/
、%
、()
、自增++
、自减--
等
<%
var a = 1;
var b = "hi";
var c = a++;
var d = a+100.232;
var e = (d+12)*a;
var f = 122228833330322.1112h
%>
Beetl
支持类似JavaScript
、Java
的条件表达式,如 >
,<
,==
,!=
,>=
, <=
以及 !
, 还有 &&
和 ||
,还有三元表达式
等
<%
var a = 1;
var b="good";
var c = null;
if(a!=1 && b=="good" && c==null){
......
}
%>
<%
var a = 1 ;
%>
${a==1 ? "ok" : ''}
${a==1 ? "ok"}
for-in
<%
for(user in userList){
print(userLP.index);
print(user.name);
}
%>
<%
for(entry in map){
var key = entry.key;
var value = entry.value;
print(value.name);
}
%>
注:对于集合本身的属性,可通过后缀LP
来获得:
for(exp; exp; exp)
<%
var a = [1,2,3];
for(var i=0; i<a.~size; i++){
print(a[i]);
}
%>
while
<%
var i = 0;
while(i<5){
print(i);
i++;
}
%>
elsefor
<%
var list = [];
for(item in list){
}elsefor{
print("未有记录");
}
%>
if-else
<%
var a =true;
var b = 1;
if(a && b==1){
}else if(a){
}else{
}
%>
switch-case
<%
var b = 1;
switch(b){
case 0:
print("it's 0");
break;
case 1:
print("it's 1");
break;
default:
print("error");
}
%>
select-case
select-case 是switch case的增强版。他允许case 里有逻辑表达式,同时,也不需要每个case都break一下,默认遇到合乎条件的case执行后就退出
<%
var b = 1;
select(b){
case 0,1:
print("it's small int");
case 2,3:
print("it's big int");
default:
print("error");
}
%>
select 后也可以不需要一个变量,这样case 后的逻辑表达式将决定执行哪个case.其格式是
<%
select {
case boolExp,orBoolExp2:
doSomething();
}
%>
<%
var b = 1;
select{
case b<1,b>10:
print("it's out of range");
break;
case b==1:
print("it's 1");
break;
default:
print("error");
}
%>
<%
try{
callOtherSystemView()
}catch(error){
print("暂时无数据");
}
%>
<% var date = date(); %>
Today is ${date,dateFormat="yyyy-MM-dd"}.
Today is ${date,dateFormat}
salary is ${salary,numberFormat="##.##"}
声明,本笔记只记录了最简单、最基本的功能的部分常用使用方式,更多使用方式、更多功能,详见官方文档或文末链接。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。