🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 2.2 自定义方法 [TOC] ### 2.2.1 实现Function ```java 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异常 ### 2.2.2 使用普通的java类 尽管实现Function对于模板引擎来说,是效率最高的方式,但考虑到很多系统只有util类,这些类里的方法仍然可以注册为模板函数。其规则很简单,就是该类的所有public方法。如果还需要Context 变量,则需要在方法最后一个参数加上Context即可,如 ```java public class util{ public String print(Object a, Context ctx){ //balabala... } } ``` 注意 > 1. 从beetl效率角度来讲,采用普通类效率不如实现Function调用 > 2. 采用的普通java类尽量少同名方法。这样效率更低。beetl调用到第一个适合的同名方法。而不像java那样找到最匹配的 > 3. 方法名支持可变数组作为参数 > 4. 方法名最后一个参数如果是Context,则beetl会传入这个参数。 ### 2.2.3 使用模板文件作为方法 可以不用写java代码,模板文件也能作为一个方法。默认情况下,需要将模板文件放到Root的functions目录下,且扩展名为.html(可以配置文件属性来修改这俩个默认值) 方法参数分别是para0,para1….. 如下root/functions/page.fn ```javascript <% //para0,para1 由函数调用传入 var current = para0,total = para1,style=para2!'simple' %> 当前页面 ${current},总共${total} ``` 则在模板中 ```javascript <% page(current,total); %> ``` 允许使用return 表达式返回一个变量给调用者,如模板文件functions\now.html ```javascript <% return date(); %> ``` 在任何模板里都可以调用: ```javascript hello time is ${now(),'yyyy-MM-dd'} ``` 也可以在functions建立子目录,这样function则具有namespace,其值就是文件夹名