about summary refs log tree commit diff stats
path: root/cmd/build/template.go
diff options
context:
space:
mode:
authorAlan Pearce2024-04-24 15:17:51 +0200
committerAlan Pearce2024-04-24 15:18:39 +0200
commit7625cb131a85d4f3c45683251702fc0f0ff3f8c2 (patch)
tree008497bb8a03f1770133602a483e3eb4770fe281 /cmd/build/template.go
parent2ef8e8286acfc06c4d7680d299e47dedea7b35eb (diff)
downloadwebsite-7625cb131a85d4f3c45683251702fc0f0ff3f8c2.tar.lz
website-7625cb131a85d4f3c45683251702fc0f0ff3f8c2.tar.zst
website-7625cb131a85d4f3c45683251702fc0f0ff3f8c2.zip
template: open files only once
Diffstat (limited to 'cmd/build/template.go')
-rw-r--r--cmd/build/template.go42
1 files changed, 31 insertions, 11 deletions
diff --git a/cmd/build/template.go b/cmd/build/template.go
index 5ea1912..b3576a2 100644
--- a/cmd/build/template.go
+++ b/cmd/build/template.go
@@ -8,6 +8,7 @@ import (
 	"net/url"
 	"os"
 	"strings"
+	"sync"
 	"time"
 	"website/internal/atom"
 	"website/internal/config"
@@ -20,16 +21,39 @@ import (
 	"golang.org/x/net/html"
 )
 
+var (
+	assetsOnce sync.Once
+	css        string
+	templates  map[string]*os.File = make(map[string]*os.File)
+)
+
+func loadTemplate(path string) (file *os.File, err error) {
+	if templates[path] == nil {
+		file, err = os.Open(path)
+		if err != nil {
+			return nil, err
+		}
+		templates[path] = file
+	}
+	file = templates[path]
+	return
+}
+
 func layout(filename string, config config.Config, pageTitle string) (*goquery.Document, error) {
-	html, err := os.Open(filename)
+	html, err := loadTemplate(filename)
 	if err != nil {
 		return nil, err
 	}
-	defer html.Close()
-	css, err := os.ReadFile("templates/style.css")
+	defer html.Seek(0, io.SeekStart)
+	assetsOnce.Do(func() {
+		var bytes []byte
+		bytes, err = os.ReadFile("templates/style.css")
+		css = string(bytes)
+	})
 	if err != nil {
 		return nil, err
 	}
+
 	doc, err := goquery.NewDocumentFromReader(html)
 	if err != nil {
 		return nil, err
@@ -178,11 +202,11 @@ func render404(config config.Config) (io.Reader, error) {
 }
 
 func renderFeed(title string, config config.Config, posts []Post, specific string) (io.Reader, error) {
-	reader, err := os.Open("templates/feed.xml")
+	reader, err := loadTemplate("templates/feed.xml")
 	if err != nil {
 		return nil, err
 	}
-	defer reader.Close()
+	defer reader.Seek(0, io.SeekStart)
 	doc, err := xmlquery.Parse(reader)
 	feed := doc.SelectElement("feed")
 	feed.SelectElement("title").FirstChild.Data = title
@@ -230,11 +254,11 @@ func renderFeed(title string, config config.Config, posts []Post, specific strin
 }
 
 func renderFeedStyles() (io.Reader, error) {
-	reader, err := os.Open("templates/feed-styles.xsl")
+	reader, err := loadTemplate("templates/feed-styles.xsl")
 	if err != nil {
 		return nil, err
 	}
-	defer reader.Close()
+	defer reader.Seek(0, io.SeekStart)
 	nsMap := map[string]string{
 		"xsl":   "http://www.w3.org/1999/XSL/Transform",
 		"atom":  "http://www.w3.org/2005/Atom",
@@ -246,10 +270,6 @@ func renderFeedStyles() (io.Reader, error) {
 		return nil, err
 	}
 	style := xmlquery.QuerySelector(doc, expr)
-	css, err := os.ReadFile("templates/style.css")
-	if err != nil {
-		return nil, err
-	}
 	xmlquery.AddChild(style, &xmlquery.Node{
 		Type: xmlquery.TextNode,
 		Data: string(css),