Bat

A mustache like ({{foo.bar}}) templating engine for Go. This is still very much WIP, but contributions and issues are welcome.

Usage

Given a file, index.batml:

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

Create a new template and execute it:

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

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

Here’s an overview of more advanced usage:

Primitives:

Bat supports the following primitives that can be used within {{}} expressions:

  • true
  • false
  • nil

Conditionals

Bat supports if statements, and the != and == operators.

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

Iterators

Iteration is supported via the range keyword. Both slices and maps are supported.

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

Given data being defined as: []string{"Fox Mulder", "Dana Scully"}, the resulting output would look like:

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

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

In the example above, range defines two variables which must begin with a $ so they don’t conflict with data passed into the template.

The range keyword can also be used with a single variable, providing only the key or index to the iterator:

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

Given data being defined as: []string{"Fox Mulder", "Dana Scully"}, the resulting output would look like:

    <h1>Hello person 0</h1>

    <h1>Hello person 1</h1>

TODO

  • Add each functionality (see the section on range)
  • Add if and else functionality
  • Emit better error messages and validate them with tests
  • Create an engine struct that will enable partials, helper functions, and custom escaping functions.
  • Support strings in templates
  • Support integer numbers
  • Add basic math operations
  • Simple map class { "foo": bar } for use with partials
  • Improve stringify logic in the executor (bat.go)
  • Support channels in range

Maybe

  • Add &&, and || operators for more complex conditionals
  • Replace {{end}} with named end blocks, like {{/if}}
  • Add support for {{else if <expression>}}
  • Support the not operator, e.g. if !foo
  • Track and error on undefined variable usage in the parsing stage

Don’t

  • Add parens for complex options
  • Variable declarations that look like provided data access

GitHub

View Github