Handlebars for Go

github.com/malcolmston/handlebars

Logic-less Handlebars/Mustache templating in pure Go.

 GitHubports handlebars-lang/handlebars.js

A dependency-free Handlebars/Mustache templating engine implemented entirely in Go's standard library. It ships its own lexer, parser and AST, then renders that tree against any value using reflection — it does not wrap text/template, so the Handlebars semantics are implemented directly and match Handlebars.js. You get escaped and raw interpolation, rich path expressions with ../parent and @root, the full set of built-in block helpers, custom helpers with hash arguments and subexpressions, partials, comments and whitespace control — over maps, structs, slices and pointers.

Install

shell
$ go get github.com/malcolmston/handlebars

Quick start

main.go
import "github.com/malcolmston/handlebars"

// One-shot render, or compile once with Parse/MustParse and reuse.
t := handlebars.MustParse("{{#each items}}{{@index}}:{{this}} {{/each}}")
out := t.MustRender(map[string]any{"items": []string{"a", "b"}})
// out == "0:a 1:b "

Features

  • Interpolation — {{expr}} HTML-escapes; {{{expr}}} and {{& expr}} emit raw, matching the Handlebars.js escape set
  • Path expressions — foo.bar.baz, index foo.0, this/., parent ../foo, @root and bracketed [a b] segments
  • Block helpers — {{#if}}/{{else}}, {{#unless}}, {{#each}} and {{#with}}, plus inverse sections {{^cond}}
  • {{#each}} over slices and maps, exposing @index, @key, @first, @last with map keys visited in sorted order
  • Built-in inline helpers — lookup, eq, ne, not, and, or, gt, lt, gte, lte — usable in subexpressions like {{#if (eq a b)}}
  • Custom helpers via RegisterHelper — positional Options.Arg, hash args Options.HashStr, block callbacks Options.Fn/Options.Inverse, and SafeString to bypass escaping
  • Partials via RegisterPartial{{> name}}, explicit context {{> name ctx}}, hash overlays and dynamic {{> (expr)}}, with indentation preserved
  • Comments {{! ... }}/{{!-- ... --}}, standalone-line stripping and explicit whitespace control with {{~ ~}} — all with zero third-party dependencies
Handlebars