compile templates only once on app start instead of on every page request
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmPclg0ACgkQO3+8IhRO Y5gdihAAkyaQTBDR7XlgHGeFPBlGSSr5UTN1rf+B9IjPLabfzGDtJBxqV9c8mBJ8 2sVk/KW9liq1UaNy+LgAsMYJCNdtc095GKxCLBPe1k1CjQ4BrzD2oqwuexVAp0Qz a10H3cz3SY9nYFj+wiifw5mvF0t+sD7YyXICFR8urthDADBpfw1ZkpqfsaSO2gXm HBazAqiu+5vNupERwl2YVNpAeTItwJZx1XFCHpqjl62t8jp3B+xOLIe7mSPs/y8+ jImjwP/NnfKXtAq0UeBqrLv6zVXpUZ28EmWbXzKrZMM/wB6xASpr6Bix40Hzf3LE xeM9XIYihFiSuhMN0qxr9/nlYsIEqK+xvGyLAFqqj0PjZvrmiOkz128HI4bGKsPU wVw2HcTXqkXS6Ne8rN2NUbvevcm7+pc+oStFRoQ8Cflqr7aBkfDVQZk3ML7J4cvy 2VMNLcJUR6dehqqJY0F24bPXd5n5BJA+2ILp3sJhx98pvUB4a0wmti+WqNu23el1 bdTg4/MbWDqcBsy/dy7Zi0VLUAH8mN18k9mI3PyJ/dt/taa772bXduaXjv4hxqaY naKPzOKcreEtTyJixKd86lDoKn1kYgHvTUJGuzsB78aIc7jeomFG/da0DSJ19UhD i9PyUadLwwInJb83Z/Amp51X9CY52lLB4K+xBQ7Oqg8pkIezpCQ= =C1Ao -----END PGP SIGNATURE-----
4 files changed,
19 insertions(+),
39 deletions(-)
M
main.go
→
main.go
@@ -3,8 +3,10 @@
import ( "flag" "fmt" + "html/template" "log" "net/http" + "path/filepath" "git.icyphox.sh/legit/config" "git.icyphox.sh/legit/routes"@@ -28,8 +30,11 @@ },
"r"); err != nil { log.Fatalf("unveil: %s", err) } + + tpath := filepath.Join(c.Dirs.Templates, "*") + t := template.Must(template.ParseGlob(tpath)) - mux := routes.Handlers(c) + mux := routes.Handlers(c, t) addr := fmt.Sprintf("%s:%d", c.Server.Host, c.Server.Port) log.Println("starting server on", addr) log.Fatal(http.ListenAndServe(addr, mux))
M
routes/handler.go
→
routes/handler.go
@@ -2,6 +2,7 @@ package routes
import ( "net/http" + "html/template" "git.icyphox.sh/legit/config" "github.com/alexedwards/flow"@@ -29,9 +30,9 @@ d.RepoIndex(w, r)
} } -func Handlers(c *config.Config) *flow.Mux { +func Handlers(c *config.Config, t *template.Template) *flow.Mux { mux := flow.New() - d := deps{c} + d := deps{c, t} mux.NotFound = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { d.Write404(w)
M
routes/routes.go
→
routes/routes.go
@@ -21,6 +21,7 @@ )
type deps struct { c *config.Config + t *template.Template } func (d *deps) Index(w http.ResponseWriter, r *http.Request) {@@ -70,14 +71,11 @@ sort.Slice(infos, func(i, j int) bool {
return infos[j].d.Before(infos[i].d) }) - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - data := make(map[string]interface{}) data["meta"] = d.c.Meta data["info"] = infos - if err := t.ExecuteTemplate(w, "index", data); err != nil { + if err := d.t.ExecuteTemplate(w, "index", data); err != nil { log.Println(err) return }@@ -138,9 +136,6 @@ if readmeContent == "" {
log.Printf("no readme found for %s", name) } - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - if len(commits) >= 3 { commits = commits[:3] }@@ -154,7 +149,7 @@ data["desc"] = getDescription(path)
data["servername"] = d.c.Server.Name data["gomod"] = isGoModule(gr) - if err := t.ExecuteTemplate(w, "repo", data); err != nil { + if err := d.t.ExecuteTemplate(w, "repo", data); err != nil { log.Println(err) return }@@ -247,9 +242,6 @@ log.Println(err)
return } - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - data := make(map[string]interface{}) data["commits"] = commits data["meta"] = d.c.Meta@@ -258,7 +250,7 @@ data["ref"] = ref
data["desc"] = getDescription(path) data["dotdot"] = filepath.Dir(path) - if err := t.ExecuteTemplate(w, "log", data); err != nil { + if err := d.t.ExecuteTemplate(w, "log", data); err != nil { log.Println(err) return }@@ -286,9 +278,6 @@ log.Println(err)
return } - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - data := make(map[string]interface{}) data["commit"] = diff.Commit@@ -299,7 +288,7 @@ data["name"] = name
data["ref"] = ref data["desc"] = getDescription(path) - if err := t.ExecuteTemplate(w, "commit", data); err != nil { + if err := d.t.ExecuteTemplate(w, "commit", data); err != nil { log.Println(err) return }@@ -332,9 +321,6 @@ d.Write500(w)
return } - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - data := make(map[string]interface{}) data["meta"] = d.c.Meta@@ -343,7 +329,7 @@ data["branches"] = branches
data["tags"] = tags data["desc"] = getDescription(path) - if err := t.ExecuteTemplate(w, "refs", data); err != nil { + if err := d.t.ExecuteTemplate(w, "refs", data); err != nil { log.Println(err) return }
M
routes/template.go
→
routes/template.go
@@ -2,42 +2,33 @@ package routes
import ( "bytes" - "html/template" "io" "log" "net/http" - "path/filepath" "strings" "git.icyphox.sh/legit/git" ) func (d *deps) Write404(w http.ResponseWriter) { - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) w.WriteHeader(404) - if err := t.ExecuteTemplate(w, "404", nil); err != nil { + if err := d.t.ExecuteTemplate(w, "404", nil); err != nil { log.Printf("404 template: %s", err) } } func (d *deps) Write500(w http.ResponseWriter) { - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) w.WriteHeader(500) - if err := t.ExecuteTemplate(w, "500", nil); err != nil { + if err := d.t.ExecuteTemplate(w, "500", nil); err != nil { log.Printf("500 template: %s", err) } } func (d *deps) listFiles(files []git.NiceTree, data map[string]any, w http.ResponseWriter) { - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - data["files"] = files data["meta"] = d.c.Meta - if err := t.ExecuteTemplate(w, "tree", data); err != nil { + if err := d.t.ExecuteTemplate(w, "tree", data); err != nil { log.Println(err) return }@@ -70,9 +61,6 @@ }
} func (d *deps) showFile(content string, data map[string]any, w http.ResponseWriter) { - tpath := filepath.Join(d.c.Dirs.Templates, "*") - t := template.Must(template.ParseGlob(tpath)) - lc, err := countLines(strings.NewReader(content)) if err != nil { // Non-fatal, we'll just skip showing line numbers in the template.@@ -90,7 +78,7 @@ data["linecount"] = lines
data["content"] = content data["meta"] = d.c.Meta - if err := t.ExecuteTemplate(w, "file", data); err != nil { + if err := d.t.ExecuteTemplate(w, "file", data); err != nil { log.Println(err) return }