The mustache template language in Go

Overview

Overview

mustache.go is an implementation of the mustache template language in Go. It is better suited for website templates than Go's native pkg/template. mustache.go is fast -- it parses templates efficiently and stores them in a tree-like structure which allows for fast execution.

Documentation

For more information about mustache, check out the mustache project page or the mustache manual.

Also check out some example mustache files

Installation

To install mustache.go, simply run go get github.com/hoisie/mustache. To use it in a program, use import "github.com/hoisie/mustache"

Usage

There are four main methods in this package:

func Render(data string, context ...interface{}) string

func RenderFile(filename string, context ...interface{}) string

func ParseString(data string) (*Template, os.Error)

func ParseFile(filename string) (*Template, os.Error)

There are also two additional methods for using layouts (explained below).

The Render method takes a string and a data source, which is generally a map or struct, and returns the output string. If the template file contains an error, the return value is a description of the error. There's a similar method, RenderFile, which takes a filename as an argument and uses that for the template contents.

data := mustache.Render("hello {{c}}", map[string]string{"c":"world"})
println(data)

If you're planning to render the same template multiple times, you do it efficiently by compiling the template first:

tmpl,_ := mustache.ParseString("hello {{c}}")
var buf bytes.Buffer;
for i := 0; i < 10; i++ {
    tmpl.Render (map[string]string { "c":"world"}, &buf)  
}

For more example usage, please see mustache_test.go

Escaping

mustache.go follows the official mustache HTML escaping rules. That is, if you enclose a variable with two curly brackets, {{var}}, the contents are HTML-escaped. For instance, strings like 5 > 2 are converted to 5 &gt; 2. To use raw characters, use three curly brackets {{{var}}}.

Layouts

It is a common pattern to include a template file as a "wrapper" for other templates. The wrapper may include a header and a footer, for instance. Mustache.go supports this pattern with the following two methods:

func RenderInLayout(data string, layout string, context ...interface{}) string

func RenderFileInLayout(filename string, layoutFile string, context ...interface{}) string

The layout file must have a variable called {{content}}. For example, given the following files:

layout.html.mustache:

<html>
<head><title>Hi</title></head>
<body>
{{{content}}}
</body>
</html>

template.html.mustache:

<h1> Hello World! </h1>

A call to RenderFileInLayout("template.html.mustache", "layout.html.mustache", nil) will produce:

<html>
<head><title>Hi</title></head>
<body>
<h1> Hello World! </h1>
</body>
</html>

A note about method receivers

Mustache.go supports calling methods on objects, but you have to be aware of Go's limitations. For example, lets's say you have the following type:

type Person struct {
    FirstName string
    LastName string    
}

func (p *Person) Name1() string {
    return p.FirstName + " " + p.LastName
}

func (p Person) Name2() string {
    return p.FirstName + " " + p.LastName
}

While they appear to be identical methods, Name1 has a pointer receiver, and Name2 has a value receiver. Objects of type Person(non-pointer) can only access Name2, while objects of type *Person(person) can access both. This is by design in the Go language.

So if you write the following:

mustache.Render("{{Name1}}", Person{"John", "Smith"})

It'll be blank. You either have to use &Person{"John", "Smith"}, or call Name2

Supported features

  • Variables
  • Comments
  • Change delimiter
  • Sections (boolean, enumerable, and inverted)
  • Partials
Comments
  • Conform to spec: empty list evaluates inverted section

    Conform to spec: empty list evaluates inverted section

    The mustache manual[1] states the following:

    While sections can be used to render text one or more times based on the
    value of the key, inverted sections may render text once based on the
    inverse value of the key. That is, they will be rendered if the key
    doesn't exist, is false, or is an empty list.
    

    The previous implementation, upon encountering an empty list, iterated over the items in the list and rendered each one. Since the list was empty, nothing would be emitted for an inverted section over an empty list, thus the following template would never have any output:

    {{#list}} not empty {{/list}}
    {{^list}} empty {{/list}}
    

    Furthermore, though the mustache spec isn't clear on what constitutes a false value, I felt that the definition in isNil was too constrained -- most primitive zero-values were not handled and defined as non-false. This, unfortunately, included common things like integers, maps, lists, etc. I have amended isNil to switch on every reflect.Kind and check for zero-value equivalents (e.g., empty lists/maps/channels/strings, 0-value numerics).

    Finally, tests have been added for these additions.

    [1] http://mustache.github.com/mustache.5.html

    opened by lye 5
  • Added RenderWriter method.

    Added RenderWriter method.

    Thanks for the great template library.

    I needed to render to an io.Writer, so I added a method called RenderWriter.

    I couldn't tell if you prefer to gofmt your code, so I didn't run it and tried to maintain your formatting. There's a new test called TestWriter and the docs were updated.

    opened by drhodes 4
  • Updated to compile with Golang weekly.2012-01-27

    Updated to compile with Golang weekly.2012-01-27

    mustache_test.go needs to be updated so that it doesn't use the container/vector package.

    Updated mustache.go to compile using golang weekly 2012-01-27. os.Error -> error, os.NewError("") -> errors.New(), os.EOF -> io.EOF, and imported new 'errors' package.

    opened by jeffbr13 3
  • assigning

    assigning "compiled" templates to a global variable

    if you "compile" a template (with ParseFile), its type is *mustache.template, that is not visible outside the package. I'd like to assign it to a (global) variable to complile once and use it everywhere in my program. So why not make it of a *mustache.Template type? I've tried a brutal name substitution in the mustache.go file, and it seems to work (sorry, I'm fairly new to both go and mustache.go). THX

    opened by gpciceri 3
  • Use Getwd(), support direct customization of the 'cwd' path

    Use Getwd(), support direct customization of the 'cwd' path

    • Not seeing a CWD envvar as of Ubuntu Linux 16.04. Probably meant PWD? May as well use the standard Getwd() for this.
    • It'd also be useful to support explicitly providing that 'cwd' value via the API. Adds a new ParseStringInDir() function to support this. It came up for me when I was trying to pass the string contents of a file, where I wanted to have both old and new versions of the content to show in a diff. Example:
    oldData, _ := ioutil.ReadFile(path)
    template, _ := mustache.ParseStringInPath(string(oldData), dir)
    newData := template.Render(map)
    // ... show diff of oldData vs newData ...
    
    • Finally, reenables a commented-out test which seems to be passing just fine...
    opened by nickbp 2
  • Sections can be lambdas (in the form of `fn(in string) string`), as per mustache spec.

    Sections can be lambdas (in the form of `fn(in string) string`), as per mustache spec.

    This is useful for implementing things such as filters (for example, transforming a static block of text into Markdown output).

    Notable changes: The parser now stores rawBody as it reads sections; reconstructing mustache-tags as appropriate. This is because the mustache spec requires that a [lambda] section be passsed in as a string literal, with mustache tags unexpanded. Since a lambda can only be detected at runtime, the parser must emit the unexpanded tags in addition to the expanded tags.

    The renderer now reflects on type "Func", calling the lambda with a string (the rawBody), and replacing the output with that function's result. (Also a string.) This does not break existing tests, though I would appreciate a third-party review for regressions.

    For future improvement / safety: we should ensure that the lambda is of type func(in string) string; and error / fall through as appropriate.

    opened by drbawb 2
  • Fix for Go 1 compatibility + panic fix on partial

    Fix for Go 1 compatibility + panic fix on partial

    1. I ran go fix to make this Go 1 compatible
    2. I fixed a panic which occured on Go 1 whenever a partial tag was processed. This was caused by trying to perform .Close() on a nil file reference.
    opened by kybernetyk 2
  • Go panics on some malformed templates

    Go panics on some malformed templates

    I tried creating a template with {{}} in an {{#enumerated_section}} and mustache.go threw a string bounds panic (full dump below). I see a number of explicit panic() calls in mustache.go so maybe this is not undesired behavior.

    PC=0x14b7f index 0<0>0
    throw: string bounds
    
    panic PC=0x8a6ec0
    throw+0x3e /Users/peter/Code/go/src/pkg/runtime/runtime.c:74
    throw(0xe11d8, 0x0)
    prbounds+0x92 /Users/peter/Code/go/src/pkg/runtime/string.c:108
    prbounds(0xe11f8, 0x0, 0x0, 0x0, 0x0, ...)
    runtime.indexstring+0x82 /Users/peter/Code/go/src/pkg/runtime/string.c:214
    runtime.indexstring(0x7c71a, 0x0, 0x0, 0x0, 0x0, ...)
    mustache.*template·parseSection+0x368 /Users/peter/Code/mustache.go/mustache.go:145
    mustache.*template·parseSection(0x127e640, 0x0, 0x9613a0, 0x0, 0x7c6d1, ...)
    mustache.*template·parse+0x439 /Users/peter/Code/mustache.go/mustache.go:192
    mustache.*template·parse(0x127e640, 0x0, 0x12750f0, 0x0)
    mustache.ParseString+0xc2 /Users/peter/Code/mustache.go/mustache.go:316
    mustache.ParseString(0x7c548, 0x0, 0x296, 0x0, 0xb0e78, ...)
    mustache.Render+0x25 /Users/peter/Code/mustache.go/mustache.go:345
    mustache.Render(0x7c548, 0x0, 0x296, 0x0, 0xb0e78, ...)
    
    opened by peterbourgon 2
  • Add dot notation support

    Add dot notation support

    According to the Mustache spec, the dot notation should be available.

    Hello {{person.name}}
    

    Other Mustache implements such as mustache.js have already done the job.

    I've achieved the feature in the lookup function, and added some tests from the spec

    opened by ddliu 1
  • attempt to fix a reflection bug

    attempt to fix a reflection bug

    I'm not sure whether this is the absolute fix as I just tried to understand why my code wouldn't work properly, and didn't want to spend the rest of the night reading the doc on the reflection package... :)

    opened by chbug 1
  • panicln no longer exists in latest release of Go

    panicln no longer exists in latest release of Go

    mustache.go can be updated:

      $ git diff
      diff --git a/mustache.go b/mustache.go
      index 146099a..18b5f7c 100644
      --- a/mustache.go
      +++ b/mustache.go
      @@ -156,7 +156,7 @@ func (tmpl *template) parseSection(section *sectionElement) os.Error {
                   tmpl.elems.Push(partial)
               case '=':
                   if tag[len(tag)-1] != '=' {
      -                panicln("Invalid meta tag")
      +                panic("Invalid meta tag")
                   }
                   tag = strings.TrimSpace(tag[1 : len(tag)-1])
                   newtags := strings.Split(tag, " ", 0)
      @@ -227,7 +227,7 @@ func (tmpl *template) parse() os.Error {
                   tmpl.elems.Push(partial)
               case '=':
                   if tag[len(tag)-1] != '=' {
      -                panicln("Invalid meta tag")
      +                panic("Invalid meta tag")
                   }
                   tag = strings.TrimSpace(tag[1 : len(tag)-1])
                   newtags := strings.Split(tag, " ", 0)
    
    opened by peterbourgon 1
  • Return errors from Render, etc

    Return errors from Render, etc

    Hi!

    This change makes functions return errors instead of returning them in the output. It is best practice and I really wouldn't want to send "line 1: interleaved closing tag: a" in a marketing email. It doesn't change any behaviour and it would be really easy for users to migrate.

    Hope that you consider merging this.

    This fixes #7 + thank you for making this library.

    opened by movitz-s 0
  • Interface change suggestion

    Interface change suggestion

    This would mean that a literal template and a layout file (or vice versa) could be mixed in the same call. What do you think? If I implemented this would you merge it? The original API would still work.

    In client code:

    // Order of arguments is irrelevant
    output := mustache.Render(
            mustache.Literal( "Here's my data: {{myData}}" ),
            mustache.LayoutFilename("./defaultlayout.mustache"),
            map[string]string{"myData":"Yes, this is my data"} )
    

    In mustache.go:

    type dataType int
    
    const (
        uninitialisedDataType dataType = iota
        templateLiteral
        templateFilename
        layoutLiteral
        layoutFilename
    )
    
    type templateDescription struct {
        dataType
        data string
    }
    
    func Render(args ...interface{}) string {
        // If the first argument is a string then behave as original API
        // If using new API then only use the first occurrences of template and layout
        // ...
    }
    
    func Literal(template string) templateDescription {
        return templateDescription{templateLiteral, template}
    }
    
    func Filename(filename string) templateDescription {
        return templateDescription{templateFilename, filename}
    }
    
    func LayoutLiteral(template string) templateDescription {
        return templateDescription{layoutLiteral, template}
    }
    
    func LayoutFilename(filename string) templateDescription {
        return templateDescription{layoutFilename, filename}
    }
    
    opened by crantok 0
  • Add option to treat missing variables as errors

    Add option to treat missing variables as errors

    This is a breaking change as it changes the API to follow the idiomatic Go convention of returning errors.

    I don't expect it to be merged since the project does not appear to be maintained, just sharing in case anyone else is looking for this functionality.

    opened by cbroglie 0
  • Support whitespace around variable names

    Support whitespace around variable names

    With reference to the mustache spec at github.com/mustache/spec, the current definition for tag content:

    The tag's content MUST be a non-whitespace character sequence NOT containing the current closing delimiter.

    However, later tests state “Superfluous in-tag whitespace should be ignored.” and include tests for {{ string }} and {{{ string }}}.

    That would tend to suggest that whitespace is allowed between the opening and closing delimiters, and the variable name. That’s how other implementations seem to work.

    opened by jabley 0
Owner
Michael Hoisie
Working on Android testing tools at Google.
Michael Hoisie
Wrapper package for Go's template/html to allow for easy file-based template inheritance.

Extemplate Extemplate is a small wrapper package around html/template to allow for easy file-based template inheritance. File: templates/parent.tmpl <

Danny van Kooten 51 Nov 13, 2022
Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application.

goview Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application. Contents Inst

foolin 309 Nov 23, 2022
Fast, powerful, yet easy to use template engine for Go. Optimized for speed, zero memory allocations in hot paths. Up to 20x faster than html/template

quicktemplate A fast, powerful, yet easy to use template engine for Go. Inspired by the Mako templates philosophy. Features Extremely fast. Templates

Aliaksandr Valialkin 2.6k Nov 18, 2022
Simple system for writing HTML/XML as Go code. Better-performing replacement for html/template and text/template

Simple system for writing HTML as Go code. Use normal Go conditionals, loops and functions. Benefit from typing and code analysis. Better performance than templating. Tiny and dependency-free.

Nelo Mitranim 4 Apr 13, 2022
A template to build dynamic web apps quickly using Go, html/template and javascript

gomodest-template A modest template to build dynamic web apps in Go, HTML and sprinkles and spots of javascript. Why ? Build dynamic websites using th

Adnaan Badr 86 Sep 28, 2022
Made from template temporalio/money-transfer-project-template-go

Temporal Go Project Template This is a simple project for demonstrating Temporal with the Go SDK. The full 20 minute guide is here: https://docs.tempo

MarkGorewicz 0 Jan 6, 2022
Go-project-template - Template for a golang project

This is a template repository for golang project Usage Go to github: https://git

KyberNetwork 4 Oct 25, 2022
Go-api-template - A rough template to give you a starting point for your API

Golang API Template This is only a rough template to give you a starting point f

Only Tunes Radio 3 Jan 14, 2022
Api-go-template - A simple Go API template that uses a controller-service based model to build its routes

api-go-template This is a simple Go API template that uses a controller-service

Pedro Espíndula 1 Feb 18, 2022
HTML template engine for Go

Ace - HTML template engine for Go Overview Ace is an HTML template engine for Go. This is inspired by Slim and Jade. This is a refinement of Gold. Exa

Keiji Yoshida 825 Nov 13, 2022
Package damsel provides html outlining via css-selectors and common template functionality.

Damsel Markup language featuring html outlining via css-selectors, extensible via pkg html/template and others. Library This package expects to exist

Daniel Skinner 24 Oct 23, 2022
Simple and fast template engine for Go

fasttemplate Simple and fast template engine for Go. Fasttemplate performs only a single task - it substitutes template placeholders with user-defined

Aliaksandr Valialkin 658 Nov 24, 2022
A handy, fast and powerful go template engine.

Hero Hero is a handy, fast and powerful go template engine, which pre-compiles the html templates to go code. It has been used in production environme

Lime 1.5k Nov 13, 2022
Jet template engine

Jet Template Engine for Go Jet is a template engine developed to be easy to use, powerful, dynamic, yet secure and very fast. simple and familiar synt

null 973 Nov 14, 2022
A complete Liquid template engine in Go

Liquid Template Parser liquid is a pure Go implementation of Shopify Liquid templates. It was developed for use in the Gojekyll port of the Jekyll sta

Oliver Steele 181 Nov 14, 2022
Useful template functions for Go templates.

Sprig: Template functions for Go templates The Go language comes with a built-in template language, but not very many template functions. Sprig is a l

null 3.3k Nov 21, 2022
The powerful template system that Go needs

Plush Plush is the templating system that Go both needs and deserves. Powerful, flexible, and extendable, Plush is there to make writing your template

Buffalo - The Go Web Eco-System 739 Nov 27, 2022
comparing the performance of different template engines

goTemplateBenchmark comparing the performance of different template engines full featured template engines Ace Amber Go Handlebars removed - Kasia Mus

null 212 Nov 17, 2022
Simple template suitable for building a webapp backend MVP written in go

A Simple Go Project Template - Suited for Webapp MVPs A simple go project structure setup with all dependencies you need to get your MVP off the groun

El Donaldo 30 Oct 23, 2022