Parse all templates in directory in Go

The Go embed package lets you embed files into the compiled application, so you don’t need to publish templates separately. Of course there are advantages and disadvantages to this approach.

Here we’re storing the templates in a map, with constants for the keys. The default behavior is to only parse the template on demand when it’s first requested, then store it in the map for future use. With the --pre-parse-templates flag, it will parse all the templates upfront, which will slow down initial load but will avoid delays going forward.

When you need the template, just call for it and use it like normal.

templates.go

package main

// Probably move this into its own package in a bigger application

import (
	"embed"
	"log"
	"text/template"
)

//go:embed templates/*.txt
var templateFs embed.FS

type TemplateName string

const (
	Template1 TemplateName = "templates/template1.txt"
	Template2 TemplateName = "templates/template2.txt"
)

var templates = map[TemplateName]*template.Template{}

// Useful for development/testing so you know right away if there's a problem parsing
// Maybe not useful in production because you know that they will parse successfully when needed
func PreParseTemplates() {
	log.Println("Preparsing templates")
	GetTemplate(Template1)
	GetTemplate(Template2)
}

func GetTemplate(tn TemplateName) *template.Template {
	t, ok := templates[tn]
	if !ok {
		log.Printf("Parsing template %s\n", tn)
		t = template.Must(template.ParseFS(templateFs, string(tn)))
		templates[tn] = t
	}
	return t
}

main.go

package main

import (
	_ "embed"
	"flag"
	"os"
)

func main() {

	var preParse bool
	flag.BoolVar(&preParse, "pre-parse-templates", false, "Pre-parse the templates on application startup")
	flag.Parse()

	if preParse {
		PreParseTemplates()
	}

	t1 := GetTemplate(Template1)
	data := struct{ Name string }{"World"}
	t1.Execute(os.Stdout, data)

	t2 := GetTemplate(Template2)
	t2.Execute(os.Stdout, data)
	t2 = GetTemplate(Template2)
	t2.Execute(os.Stdout, data)
}

templates/template1.txt

This is the first template: Hello {{.Name}}

templates/template2.txt

This is the second template: Hello {{.Name}}

Output

PS C:\Projects\hellogo> go build

PS C:\Projects\hellogo> .\hellogo.exe
2022/10/14 15:12:15 Parsing template templates/template1.txt
This is the first template: Hello World
2022/10/14 15:12:15 Parsing template templates/template2.txt
This is the second template: Hello World
This is the second template: Hello World

PS C:\Projects\hellogo> .\hellogo.exe --pre-parse-templates
2022/10/14 15:12:19 Preparsing templates
2022/10/14 15:12:19 Parsing template templates/template1.txt
2022/10/14 15:12:19 Parsing template templates/template2.txt
This is the first template: Hello World
This is the second template: Hello World
This is the second template: Hello World

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s