EasyBeetl——结构化创建Beetl表达式
部署
项目源码可以直接部署到任何服务端容器:Apache、Nginx、Nodejs…..
但是不能直接在本地用浏览器以 File 协议打开
如果需要本地使用,可以在Releases下载 easybeetl-win32-x64,解压后在根目录运行 easybeetl.exe 即可
使用
前言
所有涉及到“起点”、“终点”的下标概念,需要注意,下标要从 0 开始数,而“终点”通常是不被包括的
例如:”helloworld”中的 “ow” 子串,起点是下标 4,因为从 0 开始数,所以下标要比自然顺序(5)少了1。而终点则是 6,因为终点的下标不被包括,所以4~5 这一串字符的终点是 5 + 1 = 6
类型
easybeetl 将 beetl 表达式分为三种类型:
- 字符串
- 变量或数值
- 其他(又称为表达式)
1. 字符串
字符串类型就是需要加引号的数据,例如 "hello"
,
根据引号类型的不同,字符串又被细分为两种类型:单引号字符串和双引号字符串
2. 变量或数值
变量或数值等不需要双引号的数据,例如 15
、variable
3. 表达式
除了上述两种类型以外,所有的其他类型都归类为表达式
- beetl 函数是表达式:
isEmpty(xxx)
- 参数是表达式:
10, 20
按钮
demo演示地址中有3个按钮
- 新建/重置,用来重新创建 beetl 表达式
- 获取stack,是开发时用来debug的
- 渲染,将创建的beetl输出到 F12 控制台
行
同一层级的“行”,左边的颜色相同
右边有两个按钮,添加按钮代表这在当前行的后面(同一层级)添加一个新行
元素
行内有三个元素:方法、类型、填充值
类型
其中,只有类型为字符串或者变量或数值才需要填充值,若类型为表达式,那么将自动创建下一层级的行
方法
方法分为5大类:核心方法、基本方法、字符串方法、数组方法、正则方法
其中后4类为 beetl函数,而核心方法则是基本语法
核心方法
描述 | 语法符号 |
---|---|
表达式以字符或变量开头 | 表达式以字符或变量开头 |
字符串拼接 | + |
参数拼接 | , |
创建If | ? |
If = True | : |
If = False | : |
数值运算加法 | + |
数值运算减法 | - |
数值运算乘法 | * |
数值运算除法 | / |
括号 | () |
方法或属性调用的小数点 | . |
基本方法
描述 | 参数列表 |
---|---|
获取当前时间 | |
返回指定日期 | 日期, 格式化规则 |
打印一个对象 | 对象 |
打印一个对象并换行 | 对象 |
打印文件 | 文件地址 |
nvl | 对象, 字符串 |
判断为空 | 对象 |
判断不为空 | 对象 |
截取数字或日期 | 对象, 位数或格式 |
保留小数 | 对象, 位数 |
转换为整型 | 对象 |
转换为长整型 | 对象 |
转换为浮点数 | 对象 |
创建迭代器 | 初始值, 结束值, 步长 |
转换为json | 对象 |
获取指定cookie对象 | 对象 |
字符串方法
描述 | 参数列表 |
---|---|
判断是否以XX开头 | 对象, 查找的字符串xx |
判断是否以XX结尾 | 对象, 查找的字符串xx |
获取字符串长度 | 对象 |
截取从某个位置到末尾 | 对象, 起点 |
截取指定两个位置间的字符串 | 对象, 起点, 终点 |
以某个字符分割字符串为数组 | 对象, 正则表达式 |
判断是否存在某串字符 | 对象, 匹配字符串 |
全部英文转大写 | 对象 |
全部英文转小写 | 对象 |
替换部分字符串 | 对象, 匹配字符串, 替换字符串 |
格式化字符串 | 对象, 数量相符的参数 |
去掉字符串尾部空格 | 对象 |
格式化日期 | 对象, 格式 |
获取指定字符串第一次出现下标 | 对象 |
获取指定字符串最后一次出现下标 | 对象 |
数组方法
描述 | 参数列表 |
---|---|
返回数组的一部分 | 数组, 起点, 终点 |
删除数组的某个元素 | 数组, 元素 |
向数组添加一个元素 | 数组, 元素 |
判断数组是否包含某元素 | 数组, 元素 |
转化成数组 | 任意数量参数 |
将java集合转换为数组 | 数组 |
正则方法
描述 | 参数列表 |
---|---|
判断是否匹配 | 对象, 表达式 |
替换 | 对象, 表达式, 替换的字符串 |
查找第一个匹配的 | 对象, 表达式 |
查找所有匹配的 | 对象, 表达式 |
切分字符串返回列表 | 对象, 表达式 |
切分字符串返回列表并限制个数 | 对象, 表达式, 最多个数 |
每一层级的开头默认方法都是“表达式以字符或变量开头”,这个方法的作用是,不对填充值做任何处理
要进行字符串的拼接操作,例如 "a" + "b"
,那么在这一段中,”a” 应该使用的方法是:表达式以字符或变量开头
而 “b” 应该使用的是:字符串拼接
当然如果你以表达式开头,那么自然不用选择这个方法
总结
对于每一层级,开头的第一行,如果类型是字符串、变量或表达式,那么方法要选择“表达式以字符或变量开头”,而如果类型是表达式,那么选择对应的方法即可
对于字符串拼接,需要选择“字符串拼接”方法,但是要注意的是,上一条规则优先级更高,也就是说当前层级第一行的那个字符串或变量,要选择“表达式以字符或变量开头”。而如果第一行是表达式,第二行才是字符串拼接,那么第二行直接选“字符串拼接”即可
对于方法的变量,如果只有单个变量,直接填入方法的这一行中的“填充值”这一栏,也就是从左往右第三个单元格。如果有多个变量,那么参数列表的类型是表达式,与字符串拼接规则一样,不同的是,方法需要选择“参数拼接”
Demo地址中,添加新行时,每个层级第一行默认方法“表达式以字符或变量开头”,其他行默认“字符串拼接”。
如果上一行是“创建If”,那么创建的新行默认是“If=True”
如果上一行是“If=True”,那么创建的新行默认是“If=False”如果不是最外层,那么默认“参数拼接”
示例
例1
有一个变量 name,当 name 不为空时,返回自身,否则返回“姓名为空”
根据需求,可以手写出 beetl 表达式:${(isNotEmpty(name)?name:"姓名为空")}
如果用 easybeetl,可以如下操作:
例2
给定两个变量 name 和 age,最终要呈现的结果是:姓名:XXX,年龄:XX
手写结果:${"姓名:"+(isNotEmpty(name)?name:"空")+","+(isNotEmpty(age)?age:"空")}
easybeetl:
例3
有一个字符串变量 invoice,其可能以“发票”两个字结尾,也可能没有。要求删除发票两个字
有两个思路:要么使用 replace 替换“发票”,要么就进行复杂的判断,下面都用easybeetl给出演示
replace
复杂判断
添加自定义方法
EasyBeetl 提供了添加自定义方法的入口:extend.json
,格式如下
[
{
"value": "say",
"text": "这是自定义方法示例",
"params": "参数列表"
}
]
extend.json 是一个数组,每一个元素都是一个方法
value:方法名
text:选择框中显示的描述
params:选择框中显示的参数列表
如果使用 electron 打包的版本,extend.json 在根目录下的 /resources/app/extend.json
位置
开发
EasyBeetl 的核心是 easybeetl.js
项目源码中,index.html
与 method.html
是网页端的实现方式
下面对 easybeetl 的数据结构与算法进行介绍
数据结构
类型
EasyBeetl 将常规 beetl 表达式 ${…..} 大括号内的内容拆分为三种类型:字符串、变量或数值、其他(又称为表达式)
他们的区别表现为,字符串仅需要在两边加上双引号,变量或数值则保持原样不变,而表达式则需要经过 EasyBeetl 的复杂操作进行最终渲染
除了表现形式上的区别,在逻辑区别上,字符串、变量或数值的是最细的粒度,而表达式可以进行嵌套
内容
对于每一段内容,使用三个属性来表示:
- type,即上述类型
- method,使用的方法
- value,值
e.g.
let example = {
type: 'string_double',
value: 'hello',
method: 'appendString'
}
type 有四种值:
- 字符串:’string_double’或’string_single’,分别代表双引号和单引号字符串
- 变量或数值:’variable’
- 表达式:’expression’
value 有两种值:
- 字符串:对应类型(字符串、变量或数值)的值
- 数组:对应类型(表达式)的嵌套
method 对应 easybeetl.js
中 core 里面的所有方法(除了 exec )
方法
easybeetl.js
中的 core 提供了很多拼接语句的方法,这些方法对应上述“内容”结构中的 method 字段
easybeetl.js
默认最外层内容为:
{
type: "placeholder",
value: []
}
通过导入 easybeetl 并调用 build 方法可以获得一个全新的 placeholder
对于此数据结构,在 easybeetl 中称为 stack
easybeetl 提供了另外四个可供调用的方法:
render(stack),将 stack 渲染成 beetl 表达式
add(stack, pos, obj),将一段“内容”添加到 stack
pos 是一个数组,每一个数字代表其在每一层对应的下标,其中 placeholder 是最顶层,往这一层添加“内容”,pos数组只需要拥有一个元素
remove(stack, pos),删除指定位置的“内容”及其嵌套“内容”
set(stack, pos, options),设置指定位置“内容”的值,不改变对象引用
算法
stack 是树状结构,EasyBeetl 通过 dfs 算法进行遍历来构造 beetl 表达式