Beetl的极简之道

Stella981
• 阅读 579

跟一个同为国内流行开源软件的开发者聊天,他说beetl功能太全,代码太多。他希望的模板与语言应该简单,然后发给我一个只提供几个指令的模板引擎的链接。后来,我详细介绍beetl让他明白了Beetl的简约之处,同时我也认识到,并不是所有开发者一眼能开出beetl的核心价值:简单。本文将详细介绍Beetl的极简之道。
极简之一:简单定界符号 :Beetl支持自定义定界符号,有人为了减少对原有模板侵入性,采用了冗长的,也有人采用了传统的<%%>,对于Beetl来说,仍然可以更简单,很多用户都采用了@+回车的方式,只要输入的符号最少,但又不影响未来维护

Beetl代码
@ var a=1;b={key:value};
hello,${b.key}

需要指明的是,有的模板引擎站位符号都可以只用一个,但维护起来很麻烦,你不得不靠眼球+大脑 联合工作才能看清楚,如下是某模板引擎支持一个站位符的情况

某模板引擎

helo,#b.key.how are you?

此代码让维护者摸不清我到底要输出b,还是b.key,还是b.key.how. 所以,beet并没有支持到如此极简程度.

极简之二 条件优化 : Beetl对条件输出做了很多优化,不像java,c等编程语言,"如果不满足条件,不要做什么:,模板通常逻辑是如果不满足条件,请输出告诉用户。看看beetl提供的elsefor功能:

Beetl代码
@for(user in users){
<div>${user.name}</div>
@}elsefor{
<div> 无数据</div>
@}

如果是其他模板引擎或者jsp,则需要在for循环外先套一个if和else的判断语句。
beetl其他关于条件的优化还有select case优化,以及decode等函数提供用于条件输出。如内置的decode函数:

Beetl代码
${decode(user.gender,1,"男",2,“女”,"保密")}

还有简化的三元表达式

Beetl代码
<td class="item ${status=1?'active'}"}

这些设定都保证用户输入量极少,但代码又容易维护。

极简之三:输出 。模板输出永远是最关键地方,beetl支持将复杂的输出需求来简单的输入表。比如,安全输出功能,beetl只需要后面用一个感叹号即可。

Beetl代码
${user.wife.name!} or ${user.wife.name!"单身"}

第一个输出如果user不存在或者为空,或者user.wife为空,则不会报错,也不会输出。第二个表达式遇到这种情况这输出“单身”。如果是传统jsp代码,则代码如下:

JSP代码
<%
String output = "单身"
User user = (User)request.getAttribute("user");
if(user!=null){
User wife = user.getWife();
if(wife!=null)output = wife.name
}
%>

极简之四:严格MVC模式 : 。有的架构师认为beetl功能太全,实际上用不了这么多。Beetl提供了严格MVC支持以及自主扩展决定哪些语法可不支持。简单说,如果架构师把模板所需要的各种输出都在后台准备好,不需要模板语言复杂的渲染逻辑。beetl只需要配置严格mvc输出,就能达到所谓其他某些号称极简的模板引擎的极简指令功能。比如,允许严格MVC后,如下代码都是会报语法错的

Beetl代码
if(user.gender==1){....}  //严格模式下是错误代码
if(isMan)  //正确代码

这种严格模式使得模板变得跟为简单(当然也会有一些负面影响,这儿不详细讨论),架构师可以根据自己喜好来定制模板引擎特性以决定需要哪些指令,不需要哪些指令

极简之五:避免眼球来回工作 : 有个词是“眼球和大脑联合parse”,说的是语言特性设定过于深奥,导致开发者或者维护着不得不费神去阅读代码。貌似输入简单了,少敲了个字母,但却毁了眼睛和大脑,比如python里的区块不是用通常的{},而是用tab来分的。阅读python代码,眼球不得不频繁工作。再比如第一个例子中某模板引擎的“极简”,helo,#b.key.how are you? 是不是每次你读到这代码,你都觉得眼球转了俩个来回?Beetl代码不但是语法上采用了类似js的语法,最为重要的是使用习俗也采用了js习俗(或者java习俗),无论是开发者还是维护着,还是新手,对不会对beetl代码感到陌生,能直接上手。比如如下代码,即使你是新手,你也能知道如何增加一条,满足符合性别还必须是男性的条件

@if(user.age<18){
禁止访问 ${user.name}
@}else{

@}

很多beetl新手看一眼文档就开始上手工作,这是我甜蜜的烦恼 :),再次奉劝新手们,好歹看完文档的初级部分啊

极简之六:超简单的扩展 :模板开发,难免需要扩展,比如自定义的方法,自定义的格式化函数,自定义的html标签。Beetl扩展这些非常简单,没有复杂的特性,仅仅是写个java类而已,甚至,不需要写,直接用beetl语言写一个也行。如下代码是提供一个html标签,用来完成分页

<#page data="${user.friends}" index = "${index}" style="simple" />

此标签可以用beetl模板文件实现,如下是page.tag,放到模本根目录下的htmltag 目录里即可

@ var style = style!"simple";
<script ....

</script>

@for(item in data)

极简之七:单独测试模板 。虽然任何一个前端框架都声称mvc,模块分离,但真正能让前端人员书写模板,并能测试模板(无单独测试,就不是真正的分离)的就只有beetl。模板编写者只要写好模板,并用beetl脚本生成伪模型。然后,打开浏览器,直接访问模板文件即可。无需当前模板界的模板分离技术,如某宝的nodejs,它实在是设计过度了。详情可以参考http://ibeetl.com/community/?/question/162

极简之八:好用的插件 。beetl作者自己开发的插件,延续了beetl语言的极简。如下贴图说明

Beetl的极简之道

第1行,错误提示。使用beetl的人都觉得beetl错误提示很友好,根据错误提示能正确解决错误,插件也延续了核心的语法解析功能,因此也具备同样友好错误提示
第2行:静态文本折叠,这样开发者不需要被大量的静态文本打扰,开发者可以通过快捷键ctrl-5折叠所有静态文本
第7行:{}可以匹配,轻易找到配对的,也可以按ctrl-shift-p ,来定位到匹配的括号,如果没有定位到而有警告声,则有可能是缺少括号
第27行,可以快捷定位到ccc.btl模板,方法你懂的,还是传统的方式,ctrl+鼠标单击
模板还有许多自动插入功能,如自动插入变量,自动插入定界符号,自动注释等,插件诸多特性不一一列举,有了完备的插件,极烂的编程语言也能好用,更何况是beetl呢?

极简之九:简化Ajax开发 。beetl新增了#ajax 用标记,使得更容易采用模板引擎来开发ajax应用,从而获得很好的开发体验,以及维护性。如

<#menu/>
<#top10> ....</#top10>
<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片段结尾
}
%>

#ajax 用于告诉告诉模板引擎,此处是个局部渲染标记,标记为"userTable",对于正常渲染视图"index.html"页面,#ajax标记会被忽略,table仍能得到正常渲染。如果渲染的视图是index.html#userTable,则模板只会渲染#ajax标记得模板片段,其他部分将忽略。关于完整例子,可以参考http://beetlajax.oschina.mopaas.com/ beetl还有很多极简设计,由于难以分类就不再一一列举。有时候碰到一些不喜欢beetl的人,总说beetl包太庞大,功能太多,或者语法没有什么新意,我会有一个比喻来回敬,Beetl宛如一个新城市,地面上盖了漂亮小区和公园,地底下也铺设了大排水管道,深埋了通讯光纤。只有你入住这样城市后,你才会觉得,这是一个很宜居舒服的城市

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Beetl性能再次测试
在某个“新模板引擎”的基准测试增加Beetl,测试结果如下,可以看到Beetl还是很领先,每秒渲染80685次(我的机器是MacPro,CoreI7)BenchmarkModeCntScoreErrorUnitsBeetl.benchmarkthrpt1
Stella981 Stella981
2年前
JFinal集成Beetl静态模板
话说Beetl模板框架比Freemarker模板还要快,至于到底怎么样,目前还没有感觉到,不管那么多了,上手再说。首先需要下载beetl包:Beetl模板路径Beetl提供JFinal框架的集成,使用BeetRenderFactory类,通过如下代码注册即可完成集成:@Overridepublicvoidconf
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这