about summary refs log tree commit diff stats
path: root/internal/builder/template.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/builder/template.go')
-rw-r--r--internal/builder/template.go64
1 files changed, 43 insertions, 21 deletions
diff --git a/internal/builder/template.go b/internal/builder/template.go
index c63e1c2..5e2af1a 100644
--- a/internal/builder/template.go
+++ b/internal/builder/template.go
@@ -18,6 +18,7 @@ import (
 	"github.com/antchfx/xmlquery"
 	"github.com/antchfx/xpath"
 	mapset "github.com/deckarep/golang-set/v2"
+	"github.com/pkg/errors"
 	"golang.org/x/net/html"
 )
 
@@ -26,18 +27,19 @@ var (
 	css            string
 	countHTML      *goquery.Document
 	liveReloadHTML *goquery.Document
-	templates      map[string]*os.File = make(map[string]*os.File)
+	templates      = make(map[string]*os.File)
 )
 
 func loadTemplate(path string) (file *os.File, err error) {
 	if templates[path] == nil {
 		file, err = os.OpenFile(path, os.O_RDONLY, 0)
 		if err != nil {
-			return nil, err
+			return nil, errors.Wrapf(err, "could not load template at path %s", path)
 		}
 		templates[path] = file
 	}
 	file = templates[path]
+
 	return
 }
 
@@ -57,7 +59,8 @@ type QueryDocument struct {
 
 func NewDocumentFromReader(r io.Reader) (*QueryDocument, error) {
 	doc, err := goquery.NewDocumentFromReader(r)
-	return &QueryDocument{doc}, err
+
+	return &QueryDocument{doc}, errors.Wrap(err, "could not create query document")
 }
 
 func (q *QueryDocument) Find(selector string) *QuerySelection {
@@ -66,7 +69,8 @@ func (q *QueryDocument) Find(selector string) *QuerySelection {
 
 func NewDocumentNoScript(r io.Reader) (*goquery.Document, error) {
 	root, err := html.ParseWithOptions(r, html.ParseOptionEnableScripting(false))
-	return goquery.NewDocumentFromNode(root), err
+
+	return goquery.NewDocumentFromNode(root), errors.Wrap(err, "could not parse HTML")
 }
 
 func (root QuerySelection) setImgURL(pageURL string, pageTitle string) QuerySelection {
@@ -90,6 +94,7 @@ func (root QuerySelection) setImgURL(pageURL string, pageTitle string) QuerySele
 	output := urlTemplate.String() + "?" + q.Encode()
 	clone.Find("img").SetAttr("src", output)
 	root.AppendSelection(clone.Find("body").Children())
+
 	return root
 }
 
@@ -103,7 +108,12 @@ func layout(
 	if err != nil {
 		return nil, err
 	}
-	defer html.Seek(0, io.SeekStart)
+	defer func() {
+		_, err := html.Seek(0, io.SeekStart)
+		if err != nil {
+			panic("could not reset template file offset: " + err.Error())
+		}
+	}()
 	assetsOnce.Do(func() {
 		var bytes []byte
 		bytes, err = os.ReadFile("templates/style.css")
@@ -133,7 +143,7 @@ func layout(
 		}
 	})
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "could not set up layout template")
 	}
 
 	doc, err := NewDocumentFromReader(html)
@@ -156,6 +166,7 @@ func layout(
 	for _, link := range config.Menus["main"] {
 		nav.AppendSelection(navLink.Clone().SetAttr("href", link.URL).SetText(link.Name))
 	}
+
 	return doc.Document, nil
 }
 
@@ -196,6 +207,7 @@ func renderTags(tags Tags, config config.Config, url string) (io.Reader, error)
 		li.Find("a").SetAttr("href", fmt.Sprintf("/tags/%s/", tag)).SetText("#" + tag)
 		tagList.AppendSelection(li)
 	}
+
 	return renderHTML(doc), nil
 }
 
@@ -288,6 +300,7 @@ func render404(config config.Config, url string) (io.Reader, error) {
 	if err != nil {
 		return nil, err
 	}
+
 	return renderHTML(doc), nil
 }
 
@@ -301,10 +314,15 @@ func renderFeed(
 	if err != nil {
 		return nil, err
 	}
-	defer reader.Seek(0, io.SeekStart)
+	defer func() {
+		_, err := reader.Seek(0, io.SeekStart)
+		if err != nil {
+			panic("could not reset reader: " + err.Error())
+		}
+	}()
 	doc, err := xmlquery.Parse(reader)
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "could not parse XML")
 	}
 	feed := doc.SelectElement("feed")
 	feed.SelectElement("title").FirstChild.Data = title
@@ -312,21 +330,18 @@ func renderFeed(
 	feed.SelectElement("id").FirstChild.Data = atom.MakeTagURI(config, specific)
 	datetime, err := posts[0].Date.UTC().MarshalText()
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "could not convert post date to text")
 	}
 	feed.SelectElement("updated").FirstChild.Data = string(datetime)
 	tpl := feed.SelectElement("entry")
 	xmlquery.RemoveFromTree(tpl)
 
 	for _, post := range posts {
-		fullURL, err := url.JoinPath(config.BaseURL.String(), post.URL)
-		if err != nil {
-			return nil, err
-		}
+		fullURL := config.BaseURL.JoinPath(post.URL).String()
 		text, err := xml.MarshalIndent(&atom.FeedEntry{
 			Title:   post.Title,
 			Link:    atom.MakeLink(fullURL),
-			Id:      atom.MakeTagURI(config, post.Basename),
+			ID:      atom.MakeTagURI(config, post.Basename),
 			Updated: post.Date.UTC(),
 			Summary: post.Description,
 			Author:  config.Title,
@@ -336,7 +351,7 @@ func renderFeed(
 			},
 		}, "  ", "    ")
 		if err != nil {
-			return nil, err
+			return nil, errors.Wrap(err, "could not marshal xml")
 		}
 		entry, err := xmlquery.ParseWithOptions(
 			strings.NewReader(string(text)),
@@ -349,7 +364,7 @@ func renderFeed(
 			},
 		)
 		if err != nil {
-			return nil, err
+			return nil, errors.Wrap(err, "could not parse XML")
 		}
 		xmlquery.AddChild(feed, entry.SelectElement("entry"))
 	}
@@ -362,7 +377,12 @@ func renderFeedStyles() (io.Reader, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer reader.Seek(0, io.SeekStart)
+	defer func() {
+		_, err := reader.Seek(0, io.SeekStart)
+		if err != nil {
+			panic("could not reset reader: " + err.Error())
+		}
+	}()
 	nsMap := map[string]string{
 		"xsl":   "http://www.w3.org/1999/XSL/Transform",
 		"atom":  "http://www.w3.org/2005/Atom",
@@ -370,24 +390,24 @@ func renderFeedStyles() (io.Reader, error) {
 	}
 	doc, err := xmlquery.Parse(reader)
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "could not parse XML")
 	}
 	expr, err := xpath.CompileWithNS("//xhtml:style", nsMap)
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "could not parse XML")
 	}
 	style := xmlquery.QuerySelector(doc, expr)
 	xmlquery.AddChild(style, &xmlquery.Node{
 		Type: xmlquery.TextNode,
-		Data: string(css),
+		Data: css,
 	})
+
 	return strings.NewReader(doc.OutputXML(true)), nil
 }
 
 func renderHTML(doc *goquery.Document) io.Reader {
 	r, w := io.Pipe()
 
-	// TODO: return errors to main thread
 	go func() {
 		_, err := w.Write([]byte("<!doctype html>\n"))
 		if err != nil {
@@ -398,9 +418,11 @@ func renderHTML(doc *goquery.Document) io.Reader {
 		if err != nil {
 			log.Error("error rendering html", "error", err)
 			w.CloseWithError(err)
+
 			return
 		}
 		defer w.Close()
 	}()
+
 	return r
 }