@@ -5,61 +5,70 @@ import (
55 "html/template"
66 "net/http"
77 "path/filepath"
8+ "sync"
89)
910
1011//go:embed templates/**/*.html
1112var templatesFS embed.FS
1213
13- // Templates holds parsed templates for each page.
14+ // Templates holds lazily- parsed templates for each page.
1415type Templates struct {
16+ once sync.Once
1517 pages map [string ]* template.Template
18+ err error
1619}
1720
18- // NewTemplates loads and parses all templates from the embedded filesystem.
19- func NewTemplates () (* Templates , error ) {
20- pages := make (map [string ]* template.Template )
21+ // load parses all templates from the embedded filesystem on first call.
22+ func (t * Templates ) load () error {
23+ t .once .Do (func () {
24+ pages := make (map [string ]* template.Template )
2125
22- // Define custom template functions
23- funcMap := template.FuncMap {
24- "add" : func (a , b int ) int { return a + b },
25- "sub" : func (a , b int ) int { return a - b },
26- "supportedEcosystems" : supportedEcosystems ,
27- "ecosystemBadgeClass" : ecosystemBadgeClasses ,
28- "ecosystemBadgeLabel" : ecosystemBadgeLabel ,
29- }
30-
31- // Get all page files
32- pageFiles , err := templatesFS .ReadDir ("templates/pages" )
33- if err != nil {
34- return nil , err
35- }
36-
37- for _ , pageFile := range pageFiles {
38- if pageFile .IsDir () {
39- continue
26+ funcMap := template.FuncMap {
27+ "add" : func (a , b int ) int { return a + b },
28+ "sub" : func (a , b int ) int { return a - b },
29+ "supportedEcosystems" : supportedEcosystems ,
30+ "ecosystemBadgeClass" : ecosystemBadgeClasses ,
31+ "ecosystemBadgeLabel" : ecosystemBadgeLabel ,
4032 }
4133
42- pageName := pageFile .Name ()
43- pageName = pageName [:len (pageName )- len (filepath .Ext (pageName ))]
44-
45- // Parse all layout files + components + this page with custom functions
46- tmpl , err := template .New ("" ).Funcs (funcMap ).ParseFS (templatesFS ,
47- "templates/layout/*.html" ,
48- "templates/components/*.html" ,
49- "templates/pages/" + pageFile .Name (),
50- )
34+ pageFiles , err := templatesFS .ReadDir ("templates/pages" )
5135 if err != nil {
52- return nil , err
36+ t .err = err
37+ return
5338 }
5439
55- pages [pageName ] = tmpl
56- }
40+ for _ , pageFile := range pageFiles {
41+ if pageFile .IsDir () {
42+ continue
43+ }
5744
58- return & Templates {pages : pages }, nil
45+ pageName := pageFile .Name ()
46+ pageName = pageName [:len (pageName )- len (filepath .Ext (pageName ))]
47+
48+ tmpl , err := template .New ("" ).Funcs (funcMap ).ParseFS (templatesFS ,
49+ "templates/layout/*.html" ,
50+ "templates/components/*.html" ,
51+ "templates/pages/" + pageFile .Name (),
52+ )
53+ if err != nil {
54+ t .err = err
55+ return
56+ }
57+
58+ pages [pageName ] = tmpl
59+ }
60+
61+ t .pages = pages
62+ })
63+ return t .err
5964}
6065
6166// Render renders a page template with the given data.
6267func (t * Templates ) Render (w http.ResponseWriter , pageName string , data any ) error {
68+ if err := t .load (); err != nil {
69+ return err
70+ }
71+
6372 w .Header ().Set ("Content-Type" , "text/html; charset=utf-8" )
6473
6574 tmpl , ok := t .pages [pageName ]
0 commit comments