Wrapper package for Go's template/html to allow for easy file-based template inheritance.

  • By Danny van Kooten
  • Last update: Dec 6, 2022
  • Comments: 3

Extemplate GoDoc Build Status Go Report Card Coverage

Extemplate is a small wrapper package around html/template to allow for easy file-based template inheritance.

File: templates/parent.tmpl

	<title>{{ block "title" }}Default title{{ end }}</title>
	{{ block "content" }}Default content{{ end }} 

File: templates/child.tmpl

{{ extends "parent.tmpl" }}
{{ define "title" }}Child title{{ end }}
{{ define "content" }}Hello world!{{ end }}

File: main.go

xt := extemplate.New()
xt.ParseDir("templates/", []string{".tmpl"})
_ = xt.ExecuteTemplate(os.Stdout, "child.tmpl", "no data needed") 
// Output: <html>.... Hello world! ....</html>

Extemplate recursively walks all files in the given directory and will parse the files matching the given extensions as a template. Templates are named by path and filename, relative to the root directory.

For example, calling ParseDir("templates/", []string{".tmpl"}) on the following directory structure:

  |__ admin/
  |      |__ index.tmpl
  |      |__ edit.tmpl
  |__ index.tmpl

Will result in the following templates:


Check out the tests and examples directory for more examples.


You will most likely never have to worry about performance, when using this package properly. The benchmarks are purely listed here so we have a place to keep track of progress.

BenchmarkExtemplateGetLayoutForTemplate-8   	 2000000	       923 ns/op	     104 B/op	       3 allocs/op
BenchmarkExtemplateParseDir-8               	    5000	    227898 ns/op	   34864 B/op	     325 allocs/op






  • 1

    Fail golang test

    go version go1.14.6 windows/amd64 $ go test --- FAIL: TestLookup (0.00s) template_test.go:32: Lookup: expected template, got nil --- FAIL: TestExecuteTemplate (0.00s) template_test.go:41: ExecuteTemplate: extemplate: no template "child.tmpl" --- FAIL: TestTemplates (0.00s) template_test.go:61: template not found in set: grand-child.tmpl panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x20 pc=0x58fe92]

    goroutine 12 [running]: testing.tRunner.func1.1(0x5c95c0, 0x786810) C:/programing/sdk/go/src/testing/testing.go:988 +0x314 testing.tRunner.func1(0xc00010ea20) C:/programing/sdk/go/src/testing/testing.go:991 +0x400 panic(0x5c95c0, 0x786810) C:/programing/sdk/go/src/runtime/panic.go:969 +0x174 html/template.(*Template).escape(0x0, 0x0, 0x0) C:/programing/sdk/go/src/html/template/template.go:95 +0x42 html/template.(*Template).Execute(0x0, 0x643720, 0xc00005f9e0, 0x0, 0x0, 0x1, 0x502466) C:/programing/sdk/go/src/html/template/template.go:119 +0x36 github.com/dannyvankooten/extemplate.TestTemplates(0xc00010ea20) C:/Users/kolo/go/src/github.com/dannyvankooten/extemplate/template_test.go:65 +0x2d1 testing.tRunner(0xc00010ea20, 0x60f9f0) C:/programing/sdk/go/src/testing/testing.go:1039 +0xe3 created by testing.(*T).Run C:/programing/sdk/go/src/testing/testing.go:1090 +0x379 exit status 2 FAIL github.com/dannyvankooten/extemplate 0.164s

  • 2

    Add support for template reloading and bundling

    I finally got back to adding some tests and PRing the enhancements I described in #3.

    Apologies for the length of the PR... it definitely ended up more LOC than I'd expected. Thanks for taking a look!

    Fixes #1, #3

  • 3

    Would you like some bindata & template reloading mods?

    Hi. Thanks for putting this together! It covered about 80% of what I was planning to build and saved me a bunch of time. The additions I've made:

    • Optional automatic template reparsing on ExecuteTemplate
    • A basic compiled template/bindata scheme
    • A little bit of (backwards compatible) ExecuteTemplate syntactic sugar so you can:
    // Replace this:
    data := map[string]interface{}{
        "foo": 42,
        "bar": "abc",
    xt.ExecuteTemplate(w, "hello.html", data)
    // With this:
    xt.ExecuteTemplate(w, "hello.html", "foo", 42, "bar", "abc")

    If you're interested in any of this I'm happy to restructure as PRs to extemplate. No offense if not, as I need the changes for my stuff anyway. You can view the work in progress here: