mustache

package module
v0.0.0-...-65f6063 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 4 Imported by: 0

README

go-ruby-mustache/mustache

mustache — go-ruby-mustache

Docs License Go Coverage

A pure-Go (no cgo) implementation of Ruby's logic-less Mustache templating — the rendering engine of the mustache gem, faithful to the language-independent mustache spec. It compiles a template to a small token tree and renders it against a context drawn from the Ruby value model, so a host can render Mustache templates against its own object graph — without any Ruby runtime.

It is the Mustache backend for go-embedded-ruby, but is a standalone, reusable module with no dependency on the Ruby runtime — a sibling of go-ruby-erb (the ERB compiler) and go-ruby-liquid.

Features

Faithful to the mustache spec — 146/146 conformance examples pass across comments, interpolation, sections, inverted, partials, delimiters and ~lambdas:

  • Variables{{name}} (HTML-escaped: & < > " ') and {{{name}}} / {{&name}} (unescaped).
  • Sections{{#s}}…{{/s}} over a truthy value, a list (iterating the body per item), an empty/false value (skipped), and a lambda (invoked with the raw body, its result re-rendered against the section's delimiters).
  • Inverted sections{{^s}}…{{/s}} render only when the name is absent, false, or an empty list.
  • Comments {{! … }}, partials {{> name}} (with standalone indentation and recursion), and set-delimiter {{=<% %>=}}.
  • Dotted names {{a.b.c}} with broken-chain resolution, the implicit iterator {{.}}, and a full context-stack lookup.
  • Lambdas — interpolation lambdas (arity 0, rendered against the default delimiters) and section lambdas (arity 1, given the unprocessed body, rendered against the current delimiters), including stateful and delimiter-crossing cases.
  • Standalone lines — a section / inverted / partial / comment / set-delimiter tag alone on its line strips the whole line (the fiddly whitespace rules).

CGO-free, dependency-free, 100% test coverage, gofmt + go vet clean, and green across the six 64-bit Go targets (amd64, arm64, riscv64, loong64, ppc64le, s390x).

Install

go get github.com/go-ruby-mustache/mustache

Usage

package main

import (
	"fmt"

	"github.com/go-ruby-mustache/mustache"
)

func main() {
	out, _ := mustache.Render(
		"Hello, {{name}}!\n{{#items}}- {{.}}\n{{/items}}",
		map[string]any{
			"name":  "world",
			"items": []any{"a", "b"},
		},
		nil, // no partials
	)
	fmt.Print(out)
	// Hello, world!
	// - a
	// - b
}

The gem's class-based view API:

m := &mustache.Mustache{
	Template: `{{greeting}}, {{> who}}!`,
	Context:  map[string]any{"greeting": "Hi"},
	Partials: map[string]string{"who": "{{name}}"},
}
// A View (an mustache.Object) supplies method-style names too.
out, _ := m.Render()

Ruby value model

A context value is an any drawn from a small, fixed set of Go types, so a host can map its own object graph to and from this package:

Ruby Go
nil nil
true / false bool
Integer int, int64, *big.Int
Float float64, float32
String string
Symbol mustache.Symbol (a Hash key spelled :name)
Array []any
Hash map[string]any, map[mustache.Symbol]any, *Map
lambda / proc mustache.Lambda, func() any, func(string) any
object / view mustache.Object (exposes named methods)

A name resolves against a Hash key stored as either the string or the Symbol form, and against an Object's methods — the context-stack lookup the spec describes.

API

// Render compiles template and renders it against context, resolving partials
// from the map (an absent partial renders as ""). Core entry point.
func Render(template string, context any, partials map[string]string) (string, error)

// RenderString is Render with no partials — Mustache.render(template, context).
func RenderString(template string, context any) (string, error)

// Mustache is the gem's class-based view API.
type Mustache struct {
	Template string
	Context  any
	View     Object            // consulted for names not in Context
	Partials map[string]string
}
func (m *Mustache) Render() (string, error)

type Symbol string
type Lambda func(section string) any
type Object interface{ Method(name string) (any, bool) }
type Map    struct { /* insertion-ordered Hash */ }
func NewMap() *Map
func (m *Map) Set(key, val any)
func (m *Map) Get(key any) (any, bool)

func ToString(v any) string // Ruby to_s for interpolation

Tests & coverage

The suite embeds the mustache spec's JSON test files (go:embed) and asserts byte-identical output for every example — a deterministic, ruby-free conformance suite that alone holds coverage at 100%, so the qemu cross-arch and Windows CI lanes pass the gate. Lambda examples (whose spec data is a Ruby proc source string) are backed by the equivalent Go lambda, keyed by test name. A version-gated differential MRI oracle additionally renders a corpus with the system ruby (mustache gem) and asserts the same bytes, where ruby is present.

COVERPKG=$(go list ./... | paste -sd, -)
go test -race -coverpkg="$COVERPKG" -coverprofile=cover.out ./...
go tool cover -func=cover.out | tail -1   # 100.0%

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-mustache/mustache authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

Documentation

Overview

Package mustache is a pure-Go (CGO-free) implementation of Ruby's logic-less Mustache templating — the `mustache` gem's rendering engine — faithful to the language-independent mustache spec. It compiles a template to a small tree of tokens and renders it against a context drawn from the Ruby value model, so a host (such as go-embedded-ruby) can render Mustache templates against its own object graph without any Ruby runtime.

Ruby value model

A context value is an [any] drawn from a small, fixed set of Go types so a host can map its own object graph to and from this package:

Ruby            Go
----            --
nil             nil
true / false    bool
Integer         int, int64, *big.Int
Float           float64, float32
String          string
Symbol          Symbol (a Hash key spelled :name)
Array           []any
Hash            map[string]any, map[Symbol]any, *Map (ordered)
Lambda / proc   Lambda, func() any, func(string) any
Object          Object (an interface exposing named methods)

A Ruby Hash keyed by symbols is common in Mustache data; a plain map[string]any and a map[Symbol]any are both accepted and a name resolves against either. Everything else is coerced to a string with ToString before interpolation, matching Ruby's `to_s`.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Render

func Render(template string, context Value, partials map[string]string) (string, error)

Render compiles template and renders it against context, resolving `{{>name}}` partials from the partials map (a nil or absent partial renders as the empty string). It is the package's core entry point, equivalent to the gem's `Mustache.render(template, context)` with an explicit partial set.

context is a value from the package value model — typically a map[string]any / map[Symbol]any / *Map (a Ruby Hash), but any Value is accepted and pushed as the sole context frame. partials maps a partial name to its template source.

func RenderString

func RenderString(template string, context Value) (string, error)

RenderString renders template against context with no partials — the common one-shot form of the gem's `Mustache.render(template, context)`.

func ToString

func ToString(v Value) string

ToString coerces a Value to its Ruby String form (`to_s`) for interpolation: nil is the empty string, a bool is "true"/"false", integers and floats use Ruby's formatting, a Symbol is its bare name, and a string is itself. Other shapes fall back to Go's default formatting.

Types

type Lambda

type Lambda func(section string) Value

Lambda is a Mustache lambda. A section lambda receives the unrendered section body and returns a value rendered against the current delimiters; an interpolation lambda ignores the argument (Section is empty) and returns a value rendered against the default delimiters. Returning a string is the common case; any Value is accepted and coerced.

The func() any and func(string) any Go shapes are also accepted directly as context values and adapted to this type, so a caller need not wrap a plain closure.

type Map

type Map struct {
	// contains filtered or unexported fields
}

Map is an insertion-ordered Ruby Hash accepted as a context value. A name lookup matches a key stored as a string or a Symbol.

func NewMap

func NewMap() *Map

NewMap returns an empty ordered Map.

func (*Map) Get

func (m *Map) Get(key Value) (Value, bool)

Get returns the value for key (string or Symbol) and whether it was present.

func (*Map) Len

func (m *Map) Len() int

Len reports the number of entries.

func (*Map) Pairs

func (m *Map) Pairs() []Pair

Pairs returns the entries in insertion order. The slice must not be mutated.

func (*Map) Set

func (m *Map) Set(key, val Value)

Set inserts or replaces the entry for key.

type Mustache

type Mustache struct {
	// Template is the template source. When empty, Render renders nothing.
	Template string
	// Context is the primary view data — typically a map[string]any /
	// map[Symbol]any / *Map (a Ruby Hash). It is the bottom of the context stack.
	Context Value
	// View, when non-nil, is consulted for names not found in Context, modelling a
	// Mustache subclass's view methods. It sits below Context on the stack so
	// explicit data overrides a method of the same name (Ruby's precedence).
	View Object
	// Partials maps a partial name to its template source.
	Partials map[string]string
}

Mustache is the gem's class-based view API. It pairs a template with a view — a set of named values (a Hash) and/or an Object exposing methods — plus a partial set, mirroring a `Mustache` subclass instance. Zero value is usable: set Template and (optionally) Context / View / Partials, then call Render.

func (*Mustache) Render

func (m *Mustache) Render() (string, error)

Render renders the receiver's Template against its Context (and View, if set) and Partials — the instance form of `Mustache#render`.

type Object

type Object interface {
	Method(name string) (Value, bool)
}

Object is a Ruby object exposing named "methods" to a template — a Mustache view. Method returns the value for the named method and whether the object responds to it. A host binds its own instances behind this interface so `{{name}}` and `{{#name}}` resolve to method calls.

type Pair

type Pair struct {
	Key Value
	Val Value
}

Pair is one entry of an ordered mapping.

type Symbol

type Symbol string

Symbol is a Ruby Symbol (`:name`) used as a Hash key. A name lookup matches a Hash entry stored under either the plain string or the Symbol form, mirroring Ruby Mustache's tolerance of `{name: …}` data.

type Value

type Value = any

Value is the interface satisfied by every context value this package handles. It is purely documentary — the public API uses any.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL