最全面的beetl学习笔记,填了不少坑

一、什么是Beetl

1.1 概念

Beetl是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,它功能强大,性能良好,超过当前流行的模板引擎。而且还易学易用。

1.2 优缺点

1.2.1 优点:

易整合、性能强
性能测试对比
性能测试对比

1.2.2 缺点:

文档蛋疼、用例少、与html标签结合略显混乱

二、Beetl语法

参考官网语法 (http://ibeetl.com/guide/#beetl)

在线体验 (http://ibeetl.com/beetlonline/)


三、第一个例子:与SpringBoot集成

3.1 创建Spring boot项目(1.5.3.RELEASE)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath/>
</parent>

3.2 添加启动器依赖

<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl-framework-starter</artifactId>
    <version>1.1.60.RELEASE</version>
</dependency>

3.3 关于启动器的说明

starter 自动处理以btl结尾的视图,模板根目录是Spring Boot默认的templates目录。

3.4 使用默认配置

  • 创建HelloController(return "/hello.btl";)
  • 在templates下创建 hello.btl

3.5 启动运行效果

Hello,This is a BTL file, The time is 2018-09-05 10:09:12


四、探究Beetl模板资源加载器

4.1 字符串模板加载器

在创建GroupTemplate过程中,如果传入的是StringTemplateResourceLoader,则允许通过调用gt.getTemplate(String template)来获取模板实例对象

4.2 文件资源模板加载器

更通常情况下,模板资源是以文件形式管理的,集中放在某一个文件目录下(如webapp的模板根目录就可能是WEB-INF/template里),因此,可以使用FileResourceLoader来加载模板实例,如下代码:

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");
String str = t.render();
System.out.println(str);

4.3 Classpath资源模板加载器

还有种常情况下,模板资源是打包到jar文件或者同Class放在一起,因此,可以使用ClasspathResourceLoader来加载模板实例

ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("org/beetl/sample/s01/");
Configuration cfg = Configuration.defaultConfiguration();
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
Template t = gt.getTemplate("/hello.txt");
String str = t.render();
System.out.println(str);

第1行代码指定了模板根目录,即搜索模板的时候从根目录开始,如果new ClasspathResourceLoader("template/"),则表示搜索template下的模板。此处用空构造函数,表示搜索路径是根路径,且字符集默认字符集UTF-8.

4.4 WebApp资源模板加载器

WebAppResourceLoader 是用于web应用的资源模板加载器,默认根路径是WebRoot目录。也可以通过制定root属性来设置相对于WebRoot的的模板根路径,从安全角考虑,建议放到WEB-INF目录下

4.5 自定义资源模板加载器

有时候模板可能来自文件系统不同目录,或者模板一部分来自某个文件系统,另外一部分来自数据库,还有的情况模板可能是加密混淆的模板,此时需要自定义资源加载,继承ResouceLoader才能实现模板功能


五、Beetl的高级用法

5.1 模板配置文件

常用的配置其实就只有几个,其他的几乎不用改动

#取值开始符号
DELIMITER_PLACEHOLDER_START=${
#取值结束符号
DELIMITER_PLACEHOLDER_END=}
#beetl代码开始符号
DELIMITER_STATEMENT_START=<%
#beetl代码结束符号
DELIMITER_STATEMENT_END=%>

5.2 自定义视图名与模板位置

在application.properties中配置模版路径,beetl解析的视图名以及spring mvc的视图后缀,不建议使用Spring mvc视图前缀,直接通过模板名称与spring mvc视图后缀组合定位具体模板

#配置模板的位置为templates下的views文件夹
beetl.templatesPath=templates/views
#配置beetl的默认解析的视图名为html
beetl.suffix=html
#配置spring mvc的后缀为.html
spring.mvc.view.suffix=.html

通过以上配置,在HelloController中 return "hello"; 则表示为渲染的视图文件为 classpath:templates/views/hello.html

5.3 启动器定制GroupTemplate

新建一个java类,并将BeetlTemplateCustomize注解,注意:不要将类名称命名为BeetlConfig 别问我怎么知道的。

@Configuration
public class MyConfig{
     @Bean
     //配置自定义GroupTemplate
      public BeetlTemplateCustomize beetlTemplateCustomize(){
        return new BeetlTemplateCustomize(){
          public void customize(GroupTemplate groupTemplate){
            /*开始你的表演*/
          }
        };
      }
}

5.4 注册全局共享变量

全局共享变量可以在任何一个模板的任何一个位置使用,比如可以将后台或前台路径的path注册为全局共享变量

 Map<String,Object> map = new HashMap<String,Object>();
 map.put("name", "GouDan Li");
 groupTemplate.setSharedVars(map);

5.5 配置BeetlGroupUtilConfiguration和BeetlSpringViewResolver

使用Starter来配置已经够用,如果你想自己配置模板引擎, 通过java config来配置beetl需要的BeetlGroupUtilConfiguration,和 BeetlSpringViewResolver,参考代码如下

@Configuration
public class BeetlConf {
    //模板根目录 ,比如 "templates"
    @Value("${beetl.templatesPath}") String templatesPath;
    @Bean(name = "beetlConfig")
    public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() {
        BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
        //获取Spring Boot 的ClassLoader
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if(loader==null){
            loader = BeetlConf.class.getClassLoader();
        }
        //额外的配置,可以覆盖默认配置,一般不需要
        beetlGroupUtilConfiguration.setConfigProperties(extProperties);
        ClasspathResourceLoader cploder = new ClasspathResourceLoader(loader,templatesPath);
        beetlGroupUtilConfiguration.setResourceLoader(cploder);
        beetlGroupUtilConfiguration.init();
        //如果使用了优化编译器,涉及到字节码操作,需要添加ClassLoader
        beetlGroupUtilConfiguration.getGroupTemplate().setClassLoader(loader);
        return beetlGroupUtilConfiguration;

    }

    @Bean(name = "beetlViewResolver")
    public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
        BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
        beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
        beetlSpringViewResolver.setOrder(0);
        beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
        return beetlSpringViewResolver;
    }
 }

5.6 自定义方法

新建类实现Fucntion接口,覆盖call方法,由于call方法返回的类型为Object,所以可以实现任何返回值的方法。

public class MyMethod implements Function{
    @Override
    public Object call(Object[] paras, Context ctx) {
        //此处仅演示输出固定的String
        return "Called My Method";
    }
}

将该方法注册的方式分为两种,一种是在beetl.properties中通过FN(Function) 配置

#配置自定义函数,myFn为你注册的方法名,后面是它所在的Class位置
FN.myFn = com.xyx.demo.fn.MyFn

另外一种是在自定义GroupTemplate 时将该方法注册

groupTemplate.registerFunction("myFn", new MyFn());

在页面中直接使用“你注册的方法名”调用

${myFn()}

5.7 导入静态工具类

普通的java类中的方法亦可以被模板调用,该方法需声明为 public static,页面中调用需要把包名写上: ${@com.xyx.demo.utils.MyUtils.myUtilMethod()}

不想写包名?可以在beetl.properties中通过IMPORT_PACKAGE 配置,可以导入多个包

#导入自定义静态方法类
IMPORT_PACKAGE= com.xyx.demo.utils.;\
                com.xyx.demo.anotherutils.;

页面中调用,直接 类名.方法名

${@MyUtils.myUtilMethod()}
${@MyAnotherUtils.myAnotherUtilMethod()}

5.8 注册方法包

有时候,我们想把某个工具类中的所有方法在页面中直接调用,也是可以的,首先需要创建一个普通的java类,里面定义好所有的方法。

public class MyFnPac {
    public String MyFnPacTest() {
        return "Called MyFuntionPackageTest Method";
    }
    public String MyFnPacTest2() {
        return "Called MyFuntionPackageTest2 Method";
    }
}

注册方式同样有两种,第一种是在beetl.properties中通过FNP(Function Package)配置

#自定义的功能包
FNP.myFnPac = com.xyx.demo.fnpackage.MyFnPac

第二种是将该类在GroupTemplate中注册

//注册方法包
groupTemplate.registerFunctionPackage("myFnPac", new MyFnPac());

页面中调用采用“注册的包名”.“方法名”

//调用方式采用“注册的包名”.“方法名”
 ${myFnPac.MyFnPacTest()}
 ${myFnPac.MyFnPacTest2()}

5.9 模板文件作为方法

一个html文件,也可以作为方法,比如在分页时很有用。

默认情况下,需要将模板文件放到Root的functions目录下,且扩展名为.html(可以配置文件属性来修改这俩个默认值) 方法参数分别是para0,para1…..

新建一个functions目录下的模板文件page.html

<%
    //para0,para1 由函数调用传入
    var current = para0,total = para1;
%>
当前页面 ${current},总共${total}

模板中调用

<%
    page(1,10);
%>

允许使用return 表达式返回一个变量给调用者,如now.html,方法名为now

<%
    return date();
%>

5.10 自定义格式化函数

新建类实现Format接口,覆盖format方法,由于format方法返回的类型为Object,所以可以实现任何返回值的方法。

public class MyFormat implements Format{
    @Override
    public Object format(Object data, String pattern) {
        /*安排的妥妥的*/
        return data;
    }
}

5.11 自定义标签

标签形式有俩种,一种是标签函数,第二种是html tag。第二种实际上在语法解析的时候会转化成第一种,其实现是HTMLTagSupportWrapper,此类将会寻找root/htmltag目录下同名的标签文件作为模板来执行。
自定义标签的位置默认在root下的htmltag文件夹内,并以.tag为结尾,可修改。

    定义: 在htmltag目录下创建mytag.tag文件
    
    使用: 模板中<#mytag />

5.12 布局示例

在root下创建include文件夹,创建需要引入的页面

//引入头部页面
<% include('/include/header.html'){} %>
//引入左侧页面
<% include('/include/left.html'){} %>
//引入主页面(layoutContent 是默认变量)
<div class = "content">${layoutContent}</div>
//引入脚部页面
<% include('/include/footer.html'){} %>

在主页面使用layout方法采用此布局

<% layout("/layout/layout.html"){ %>
    //开始你的表演
<% } %>

六、附录

附录

标签: beetl

仅有一条评论

  1. 深作 深作

    我之前弄过一个模板 用freemarker弄的 看得我头晕

添加新评论

icon_mrgreen.pngicon_neutral.pngicon_twisted.pngicon_arrow.pngicon_eek.pngicon_smile.pngicon_confused.pngicon_cool.pngicon_evil.pngicon_biggrin.pngicon_idea.pngicon_redface.pngicon_razz.pngicon_rolleyes.pngicon_wink.pngicon_cry.pngicon_surprised.pngicon_lol.pngicon_mad.pngicon_sad.pngicon_exclaim.pngicon_question.png