文档章节

模板引擎Beet的6大创新点

闲大赋
 闲大赋
发布于 2015/08/02 21:28
字数 2191
阅读 1136
收藏 6

   2011年发布Beetl 0.5的时候,新闻是在Iteye上发布的,老资格程序员可能预料Iteye上会发生什么了,我收到的最多的不是鼓励和喝彩,而是吐槽,”又是一个轮子“是里面最大的声音。尽管4年前的版本还只是个雏形,但实际上已经开始有了与众不同创新点。我将在本文介绍一下Beetl的创新点和创新思路,希望有志从事开源开发的人能借鉴

首先,Beetl是一个脚本风格的模板,这顺应了新时代程序员的审美。

    freemarker 当初为什么能从模板引擎中脱颖而出,其实与当时XML流行无不关系。程序员习惯了用XML来处理问题,配置也好,流程说明也好,交互接口也好,无处不有XML,像我一样的大多数程序员,自然就接收了freemaker, 当我在确定Beetl的风格的时候,首先就排除了XML,因为2010后,XML已经不流行了,程序员更加务实了。我打开记事本,写了几种风格的模板语法,最后还是确定了类似JS风格

var a = 1;
var b= a+2;
for(item in items){
    print(item.name);
}


 
    尽管语法上没有创新,但将脚本风格的语法应用在模板上还是创新的,独此一家。这是因为:

  • 视图渲染往往有更复杂的渲染逻辑,freemaker的xml风格,还是velociy指令风格,力不从心。脚本风格顺应了视图渲染更加复杂和难搞这一事实。
  • JS 语法渗透了现在各个编程各个方面,程序员习惯了JS语法,也自然习惯了在模板引擎中使用类似js语法风格的模板引擎

其次,Beetl 能自定义定界符和控制符号,独此一家

  模板语言是嵌入在模板里的,所有涉及到定界符号和站位符号,其他模板语言定界符号都是固定的,如JSP总是用<%%> ,php 用的是<?  ?>,veclociy 是采用# 和回车换号符号。Beetl 则完全能自定义定界符和占位符号,适用于各种应用场景,比如可以定义#和回车作为定界符号

#for(item in items){
<td>${item.name}</td>
#}

也可以定义注释符号作为定界符

<!--: for(item in items){ -->
<td>${item.name}</td>
<!--:}-->

   正如Beetl能自定义定界符和站位符号,Beetl也许是唯一一个能用beetl模板生成beetl模板的模板引擎,而其他模板引擎则太费劲才能完成这个任务

第三: Beetl能对语法树做定制,从而改变渲染逻辑的模板引擎,又是独此一家的模板引擎

    Beetl在线体验里,有beetl语法体验,可以输入beetl代码,运行,获得期望输出,如果用户输入while(true), 这将对服务器造成伤害,大部分后来跟随Beetl的在线体验模板引擎,比如freemarker,rythmn,tinytemplate 都对此无能为力,或者通过kill thread方式来避免用户乱搞。但Beetl不是,Beetl定制了While循环处理节点,循环超过5次就结束循环。

     还有在我主导的另外一个开源Beetl SQL里,也有类似需要,如下SQL模板,

select * from user where 1=1 
-- if(user.name!=null)
and name = ${user.name}
--}

(注,--是定界符,伪装成注释,这样容易在sql客户端调试)当执行模板的时候,${user.name} 并不是需要输出其属性值,而是需要输出?,并记录其值以便随后操作

select * from user where 1=1 
and name = ?
只需要定制Beetl模板引擎,修改 PlaceholderST   节点,改成如下代码即可
public final void execute(Context ctx)
{
	Object value = expression.evaluate(ctx);
	ctx.byteWriter.writeString("?");
	List list = (List)ctx.getGlobal("_paras");
	list.add(value);
}

定制模板引擎作为高级特性,已经有数个项目被应用到,这在其他模板引擎里不可想象的

第四:Beetl 支持Ajax标记,完美将模板开发和Ajax开发结合起来。

  在Beetl推出Ajax标记之前,前端开发者都认为模板引擎和Ajax水火不容,Beet改变了这个现状,通过推出Ajax标志支持,完美结合了模板引擎渲染和无刷新的Ajax。消除了各自的缺点

<div id="table-container" >
<%
//ajax片段开始
#ajax userTable: {
%>

<table>
        <tr><td width=100>id</td><td width=100>姓名</td></tr>
        <%for(user in users){%>
        <tr><td>${user.id}</td><td>${user.name}</td></tr>
        <%}%>
</table>

当前页面<span id="current">${page!1}</span><span style="width:20px"></span>
<a href="#"><span  class="page">next</span></a> <a href="#" ><span  class="page">pre</span></a>
<%
//ajax片段结尾
}
%>

如上代码所示,如果渲染整个页面,如render("user.html").则ajax标记忽略,模板正常渲染,如果后台仅仅渲染render("user.html#userTable"); 则模板引擎会找到userTable 的标记,仅仅渲染这一部分。

正如在我的文章里提到过,单纯用js来实现ajax,会有一些问题,如

  • SEO无法优化,搜索引擎无能为力
  • 头一次访问页面无法立即看到内容,
  • 还有对服务器造成过多并发量等

用了Beetl Ajax标记,能完美解决这些问题,其他模板引擎,无论是老资格Freemaker,还是新出现的tinytemplate,都不具备这个功能。我觉得这些模板引擎应该顺应web技术发展新方向,像Beetl那样推出ajax局部渲染技术

第五,Beetl支持单独模板测试,无需控制层以及其提供的模型

   尽管所有模板引擎支持MVC分层开发,但实际上在Beetl之前,谁能正正提供分层呢?所谓分层开发,不但是可以单独开发,而且还需要单独测试而无需其他层(M和V)。也只有Beetl才能做到这真正做到一点,关于如何实现,可以参考官网,或者我的一个开源项目BingoUI,没有用任何后台代码实现的一个UI标签库,一套前端代码同时支持pc和mobile

第六,模板语法里有创新语法,也借鉴了其他语言的语法。

Beetl虽然引用在模板领域,但实际上本质上时个脚本语言,为了模板输出定制的语言,因此他有许多创新语法,着在其他模板引擎里很少有,或者他们都是借鉴Beetl的

  1. 安全输出,user.wfie.name!"单身",安全输出指不存在或者为null的时候输出,可以是常量或者表达式
  2. 省略的三元表达式,${success?"checked"},如果条件为true,输出checked,否则,什么都不输出
  3. for(){ } elsefor {}  不像java等语言,如果没有进入循环,什么事情都不需要做,模板语言则不同,因此提供elsefor,这是为模板引擎定制的
  4. directive safe_output_open 指令,比如打开安全输出,这样,后面代码都不需要输入安全输出符号!
  5. 模板变量,允许模板输出到一个变量里,方便以后使用,如在继承布局里经常使用模板变量
  6. ajax标记,如前说叙
  7. select- case 语法,类似go或者swift里的switch-case
  8. 虚拟属性语法 如 list.~size.

除此之外,还有很多实用功能,,比如

  1. 结合本地调用安全管理器,直接调用java代码
  2. html 标签(定制后能支持父子标签,貌似只有jsp tag能做到)
  3. 绑定标量的html标签,如<#cms:content id = "" var ="item">...</#cms:content>
  4. 最完善的错误提示,甚至因为中文标点导致语法错的提示都有

 总结 

   Beetl是个功能强大模板引擎,是除了jsp以外,唯一同时兼顾了脚本和标签的模板语言,本文仅仅列出了Beetl创新部分,回击那些轮子党的轮子言论(尽管轮子党人数庞大,但他们只有一个言论,这很搞笑),让有志从事开源的开发者们借鉴我的开源思路。  同时本文也展示了模板引擎的生命力仍然可以持续和古老的模板引擎技术仍然发扬光大,顺应时代潮流和现代程序审美观。


© 著作权归作者所有

闲大赋

闲大赋

粉丝 1276
博文 104
码字总数 100263
作品 10
西城
架构师
私信 提问
加载中

评论(18)

李嘉图
李嘉图
666,一看就是个有想法的老男人.13
闲大赋
闲大赋 博主

引用来自“微默”的评论

您考虑写一个源码分析吗。我很想学习您的beetl源码,奈何东西太多。
不考虑,太花时间
微默
您考虑写一个源码分析吗。我很想学习您的beetl源码,奈何东西太多。
开源中国社区酱油哥
开源中国社区酱油哥
跟人用beetl做了些小项目,慢慢的发现已经习惯使用beetl,希望越做越好
l
lijianlin5206
公司项目一直在用
K
Kevin.Gu
79支持,好用
i刘晓伟
i刘晓伟
用过好些模版引擎了,beetl真心不错。最近在看Dreamlu的JFinal+beetl的相关视频教程,希望能学到更多。。。
t
tide2046
最简洁好用的模板引擎,没有之一。支付大赋
Osheep
Osheep
迅速赞领沙发!!!
如梦技术
如梦技术

引用来自“孤独的3”的评论

用过好些模版引擎了,beetl真心不错。最近在做JFinal+beetl的视频教程,希望能帮到更多的朋友[13]

引用来自“程序猿猴”的评论

看过你的博客,我先在也是用jfinal+beetl开发。但是研究的不是太深,期待你的教程,到时候记得@一下
随时欢迎!
Beetl 2.7.6 发布,Java 模板引擎

本次发布主要是响应了 jfinal 3.0 接口变化。本年度总共发布了 21 个版本,完善了 65 个功能点,年底该休息了,祝大家新年快乐! #290:JFinal 3.0 支持 #291:循环变量 LP 变量类型推测错误...

闲大赋
2017/01/23
1K
23
Beetl 2.2.3 发布, java 模板引擎

Beetl 2.2.3 发布 新增功能: #163:增加一个用于Web的异常显示WebErrorHandler #162:非ajax页面使用ajax锚点,给出详细提示信息 #161:parseInt等函数输入参数如果为null,给出明确提示。 #159...

闲大赋
2015/06/09
2.4K
18
Checking Table 设计模式 - 从概念、建模、设计到实现

文章转自 IBM developerWorks 简介: 如何基于业务需求驱动理念来开展我们的模式创新,成为了当今架构师、设计师的重要职责之一。本文通过具体的 Checking Table 设计模式案例创新过程,阐述...

IBMdW
2011/06/11
400
1
Hello 2019! Hanjst/汉吉斯特 模板语言及引擎创新发布

Hello 2019! Hanjst/汉吉斯特 模板语言及引擎创新发布。 值此一元复始之际,恭祝 网友们新年万事如意! 寄望 Hanjst/汉吉斯特能帮助大家从各种模板中解脱出来,为人类做出更大的贡献。 1. 背...

wadelau
01/01
22
0
推荐PHPCMS V9网站系统

PHPCMS V9(后面简称V9)采用PHP5+MYSQL做为技术基础进行开发。V9采用OOP(面向对象)方式进行基础运行框架搭建。模块化开发方式做为功能开发 形式。框架易于功能扩展,代码维护,优秀的二次...

xiaogg
2011/11/08
201
0

没有更多内容

加载失败,请刷新页面

加载更多

golang-字符串-地址分析

demo package mainimport "fmt"func main() {str := "map.baidu.com"fmt.Println(&str, str)str = str[0:5]fmt.Println(&str, str)str = "abc"fmt.Println(&s......

李琼涛
今天
4
0
Spring Boot WebFlux 增删改查完整实战 demo

03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello 。这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD WebFlux 应用,让开发更方便。这里...

泥瓦匠BYSocket
今天
6
0
从0开始学FreeRTOS-(列表与列表项)-3

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
今天
4
0
Java反射

Java 反射 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的 Class,Class 类 用于表示.class 文件(字节码)) 一、反射的概述 定义:JAVA 反射机制是在运行状态中,对于任...

zzz1122334
今天
5
0
聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部