为Go提供的直观的模板引擎

45 阅读2分钟

Bat

一个类似于小胡子({{foo.bar}} )的围棋模板引擎。这仍然是一个WIP,但欢迎大家提供意见和问题。

使用方法

给定一个文件,index.batml

<h1>Hello {{Team.Name}}</h1>

创建一个新的模板并执行它:

content, _ := ioutil.ReadFile("index.bat")
bat.NewTemplate(content)

t := team{
    Name: "Foo",
}
bat.Execute(map[string]any{"Team": team})

下面是更多高级用法的概述。

基元

Bat支持以下基元,可以在{{}}表达式中使用:

  • true
  • false
  • nil

条件式

Bat支持if 语句,以及!=== 操作符:

{{if user != nil}}
    <a href="/login">Login</a>
{{else}}
    <a href="/profile">View your profile</a>
{{end}}
    

迭代器

迭代是通过range 关键字支持的。同时支持切片和映射:

{{range $index, $name in data}}
    <h1>Hello {{$name}}, number {{$index}}</h1>
{{end}}
    

鉴于data 被定义为,[]string{"Fox Mulder", "Dana Scully"},得到的输出结果是这样的:

   <h1>Hello Fox Mulder, number 0</h1>

    <h1>Hello Dana Scully, number 1</h1>    

在上面的例子中,range定义了两个变量,这些变量必须以$开头,这样它们就不会与传入模板的data 冲突。

range 关键字也可以用于单个变量,只提供迭代器的键或索引:

{{range $index in data}}
    <h1>Hello person {{$index}}</h1>
{{end}}
    

鉴于data 被定义为。[]string{"Fox Mulder", "Dana Scully"},得到的输出结果会是这样的:

  <h1>Hello person 0</h1>

    <h1>Hello person 1</h1>   

TODO

  • 增加each 的功能(见range 部分)。
  • 增加ifelse 功能
  • 发出更好的错误信息,并用测试来验证它们
  • 创建一个引擎结构,以实现参数、辅助函数和自定义转义函数。
  • 支持模板中的字符串
  • 支持整数
  • 增加基本的数学运算
  • 简单的地图类{ "foo": bar } ,用于参数的使用
  • 改进执行器(bat.go)中的字符串化逻辑
  • 支持通道在range

也许

  • 为更复杂的条件添加&&,和||操作符
  • 用命名的结束块取代{{end}} ,如{{/if}}
  • 增加对{{else if <expression>}}
  • 支持not操作符,例如if !foo
  • 在解析阶段对未定义变量的使用进行跟踪和出错

不要

  • 为复杂的选项添加后缀
  • 看起来像提供数据访问的变量声明