Skip to content

Instantly share code, notes, and snippets.

@rorycl
Created March 31, 2025 17:40
Show Gist options
  • Save rorycl/ee841bbee0f1bf9389c7af8481cd1cce to your computer and use it in GitHub Desktop.
Save rorycl/ee841bbee0f1bf9389c7af8481cd1cce to your computer and use it in GitHub Desktop.
Cache golang parsed templates to avoid reparsing unless in development mode
package main
// Assumes a directory next to this file called "templates"
// containing "home.html", "forest.html"
import (
"embed"
"fmt"
"html/template"
"io"
"io/fs"
"os"
)
//go:embed templates
var templates embed.FS
type cachedTemplate struct {
fs fs.FS
templates map[string]*template.Template
inDevelopment bool
}
func NewCachedTemplate(dir string, inDevelopment bool) (*cachedTemplate, error) {
_, err := os.Stat(dir)
if err != nil {
return nil, err
}
c := cachedTemplate{
inDevelopment: inDevelopment,
templates: map[string]*template.Template{},
}
if inDevelopment {
c.fs = os.DirFS(dir)
} else {
c.fs, err = fs.Sub(templates, dir)
if err != nil {
return nil, err
}
}
return &c, nil
}
func (c *cachedTemplate) ParseFS(name string, pages ...string) error {
var err error
if !c.inDevelopment {
if _, ok := c.templates[name]; ok {
// cache hit
return nil
}
}
c.templates[name], err = template.ParseFS(c.fs, pages...)
return err
}
func (c *cachedTemplate) Execute(name string, w io.Writer, data any) error {
tpl, ok := c.templates[name]
if !ok {
return fmt.Errorf("template %s not yet parsed", name)
}
return tpl.Execute(w, data)
}
func main() {
earlyExit := func(err error) {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
c, err := NewCachedTemplate("templates", false)
earlyExit(err)
err = c.ParseFS("home", "home.html", "forest.html")
earlyExit(err)
err = c.Execute("home", os.Stdout, map[string]string{"Name": "Totoro"})
earlyExit(err)
// cachehit?
err = c.ParseFS("home", "home.html", "forest.html")
earlyExit(err)
err = c.Execute("home", os.Stdout, map[string]string{"Name": "Totoro"})
earlyExit(err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment