您当前的位置: 首页 > 

科技D人生

暂无认证

  • 0浏览

    0关注

    1550博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Beetl学习总结(3)——高级功能

科技D人生 发布时间:2016-11-07 15:21:41 ,浏览量:0

3.1. 配置GroupTemplate

Beetl建议通过配置文件配置配置GroupTemplate,主要考虑到未来可能IDE插件会支持Beetl模板,模板的属性,和函数等如果能通过配置文件获取,将有助于IDE插件识别。 配置GroupTemplate有俩种方法

  • 配置文件: 默认配置在/org/beetl/core/beetl-default.properties 里,Beetl首先加载此配置文件,然后再加载classpath里的beetl.properties,并用后者覆盖前者。配置文件通过Configuration类加载,因此加载完成后,也可以通过此类API来修改配置信息

  • 通过调用GroupTemplate提供的方法来注册函数,格式化函数,标签函数等

配置文件分为三部分,第一部分是基本配置,在第一节讲到过。第二部分是资源类配置,可以在指定资源加载类,以及资源加载器的属性,如下

1
2
3
4
5
6
RESOURCE_LOADER=org.beetl.core.resource.ClasspathResourceLoader
#资源配置,resource后的属性只限于特定ResourceLoader
#classpath 根路径
RESOURCE.root= /
#是否检测文件变化
RESOURCE.autouCheck= true

第一行指定了类加载器,第二行指定了模板根目录的路径,此处/ 表示位于classpath 根路径下,第三行是否自动检测模板变化,默认为true,开发环境下自动检测模板是否更改。关于如何如何自定义ResouceLoader,请参考下一章

配置文件第三部分是扩展部分,如方法,格式化函数等

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#####  扩展 ##############
## 内置的方法
FN.date = org.beetl.ext.fn.DateFunction
FN.nvl = org.beetl.ext.fn.NVLFunction
.................
##内置的功能包
FNP.strutil = org.beetl.ext.fn.StringUtil

##内置的格式化函数
FT.dateFormat =  org.beetl.ext.format.DateFormat
FT.numberFormat =  org.beetl.ext.format.NumberFormat
.................

##内置的默认格式化函数
FTC.java.util.Date = org.beetl.ext.format.DateFormat
FTC.java.sql.Date = org.beetl.ext.format.DateFormat

## 标签类
TAG.include= org.beetl.ext.tag.IncludeTag
TAG.includeFileTemplate= org.beetl.ext.tag.IncludeTag
TAG.layout= org.beetl.ext.tag.LayoutTag
TAG.htmltag= org.beetl.ext.tag.HTMLTagSupportWrapper

FN前缀表示Function,FNP前缀表示FunctionPackage,FT表示format函数,FTC表示类的默认Format函数,TAG表示标签类。Beetl强烈建议通过配置文件加载扩展。以便随后IDE插件能识别这些注册函数

3.2. 自定义方法
3.2.1. 实现Function
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class Print implements Function
{

        public String call(Object[] paras, Context ctx)
        {
                Object o = paras[0];

                if (o != null)
                {
                        try
                        {
                                ctx.byteWriter.write(o.toString());
                        }
                        catch (IOException e)
                        {
                                throw new RuntimeException(e);
                        }
                }
                return "";

        }

call方法有俩个参数,第一个是数组,这是由模板传入的,对应着模板的参数,第二个是Context,包含了模板的上下文,主要提供了如下属性

  • byteWriter 输出流

  • template 模板本身

  • gt GroupTemplate

  • globalVar 该模板对应的全局变量

  • byteOutputMode 模板的输出模式,是字节还是字符

  • safeOutput 模板当前是否处于安全输出模式

  • 其他属性建议不熟悉的开发人员不要乱动

1 call方法要求返回一个Object,如果无返回,返回null即可

2 为了便于类型判断,call方法最好返回一个具体的类,如date函数返回的就是java.util.Date

3 call方法里的任何异常应该抛出成Runtime异常

3.2.2. 使用普通的java类

尽管实现Function对于模板引擎来说,是效率最高的方式,但考虑到很多系统只有util类,这些类里的方法仍然可以注册为模板函数。其规则很简单,就是该类的所有public方法。如果需还要Context 变量,则需要在方法最后一个参数加上Context即可,如

1
2
3
4
5
6
7
8
public class util
{

        public String print(Object a, Context ctx)
        {
                ...............

        }

注意

1 从beetl效率角度来讲,采用普通类效率不如实现Function调用

2 采用的普通java类尽量少同名方法。这样效率更低。beetl调用到第一个适合的同名方法。而不像java那样找到最匹配的

3 方法名支持可变数组作为参数

4 方法名最后一个参数如果是Context,则beetl会传入这个参数。

3.2.3. 使用模板文件作为方法

可以不用写java代码,模板文件也能作为一个方法。默认情况下,需要将模板文件放到Root的functions目录下,且扩展名为.html(可以配置文件属性来修改此俩默认值) 方法参数分别是para0,para1…..

如下root/functions/page.fn

1
2
3
4
5
当前页面 ${current},总共${total}

则在模板中

1
2
3
 
         

允许使用return 表达式返回一个变量给调用者,如模板文件functions\now.html

1
2
3
 
         

在任何模板里都可以调用:

1
hello time is ${now(),‘yyyy-MM-dd’}

也可以在functions建立子目录,这样function则具有namespace,其值就是文件夹名

3.3. 自定义格式化函数

需要实现Format接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class DateFormat implements Format
{

        public Object format(Object data, String pattern)
        {
                if (data == null)
                        return null;
                if (Date.class.isAssignableFrom(data.getClass()))
                {
                        SimpleDateFormat sdf = null;
                        if (pattern == null)
                        {
                                sdf = new SimpleDateFormat();
                        }
                        else
                        {
                                sdf = new SimpleDateFormat(pattern);
                        }
                        return sdf.format((Date) data);

                }
                else
                {
                        throw new RuntimeException("Arg Error:Type should be Date");
                }
        }

data 参数表示需要格式化的对象,pattern表示格式化模式,开发时候需要考虑pattern为null的情况

也可以实现ContextFormat 类抽象方法,从而得到Context,获取外的格式化信息。

1
        public abstract Object format(Object data,String pattern,Context ctx);
3.4. 自定义标签

标签形式有俩种,一种是标签函数,第二种是html tag。第二种实际上在语法解析的时候会转化成第一种,其实现是HTMLTagSupportWrapper,此类将会寻找root/htmltag目录下同名的标签文件作为模板来执行。类似普通模板一样,在此就不详细说了

3.4.1. 标签函数

标签函数类似jsp2.0的实现方式,需要实现Tag类的render方法即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class DeleteTag extends Tag
{

        @Override
        public void render()
        {
                // do nothing,just ignore body
                ctx.byteWriter.write("被删除了,付费可以看")

        }

}

如上一个最简单的Tag,将忽略tag体,并输出内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class XianDeDantengTag extends Tag
{

        @Override
        public void render()
        {
                doBodyRender();

        }

}

此类将调用父类方法doBodyRender,渲染tag body体

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class CompressTag extends Tag
{

        @Override
        public void render()
        {
                BodyContent  content = getBodyContent();
                String content = content.getBody();
                String zip = compress(conent);
                ctx.byteWriter.write(zip);

        }

}

此类将调用父类方法getBodyContent ,获得tag body后压缩输出

tag类提供了如下属性和方法供使用

  • args 传入标签的参数

  • gt GroupTemplate

  • ctx Context

  • bw 当前的输出流

  • bs 标签体对应的语法树,不熟悉勿动

3.5. 自定义虚拟属性

可以为特定类注册一个虚拟属性,也可以为一些类注册虚拟属性

  • public void registerVirtualAttributeClass(Class cls, VirtualClassAttribute virtual) 实现VirtualClassAttribute方法可以为特定类注册一个需要属性,如下代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
gt.registerVirtualAttributeClass(User.class, new VirtualClassAttribute() {

        @Override
        public String eval(Object o, String attributeName, Context ctx)
        {

                User user = (User) o;
                if(attributeName.equals("ageDescritpion")){
                        if (user.getAge()             
关注
打赏
1662604032
查看更多评论
立即登录/注册

微信扫码登录

0.1455s