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