diff options
Diffstat (limited to 'internal/builder/template.go')
-rw-r--r-- | internal/builder/template.go | 64 |
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 } |