diff options
Diffstat (limited to 'cmd/build/template.go')
-rw-r--r-- | cmd/build/template.go | 87 |
1 files changed, 75 insertions, 12 deletions
diff --git a/cmd/build/template.go b/cmd/build/template.go index b56b7dd..32f408f 100644 --- a/cmd/build/template.go +++ b/cmd/build/template.go @@ -24,6 +24,7 @@ import ( var ( assetsOnce sync.Once css string + countHTML *goquery.Document templates map[string]*os.File = make(map[string]*os.File) ) @@ -39,7 +40,59 @@ func loadTemplate(path string) (file *os.File, err error) { return } -func layout(filename string, config config.Config, pageTitle string) (*goquery.Document, error) { +var ( + imgOnce sync.Once + img *goquery.Selection + urlTemplate *url.URL +) + +type QuerySelection struct { + *goquery.Selection +} + +type QueryDocument struct { + *goquery.Document +} + +func NewDocumentFromReader(r io.Reader) (*QueryDocument, error) { + doc, err := goquery.NewDocumentFromReader(r) + return &QueryDocument{doc}, err +} + +func (q *QueryDocument) Find(selector string) *QuerySelection { + return &QuerySelection{q.Document.Find(selector)} +} + +func NewDocumentNoScript(r io.Reader) (*goquery.Document, error) { + root, err := html.ParseWithOptions(r, html.ParseOptionEnableScripting(false)) + return goquery.NewDocumentFromNode(root), err +} + +func (root QuerySelection) setImgURL(pageURL string, pageTitle string) QuerySelection { + clone := countHTML.Clone() + imgOnce.Do(func() { + var err error + img = clone.Find("img") + attr, _ := img.Attr("src") + if attr == "" { + panic("<img> does not have src attribute") + } + urlTemplate, err = url.Parse(attr) + if err != nil { + panic(err.Error()) + } + }) + q := urlTemplate.Query() + urlTemplate.RawQuery = "" + q.Set("p", pageURL) + q.Set("t", pageTitle) + output := urlTemplate.String() + "?" + q.Encode() + clone.Find("img").SetAttr("src", output) + root.AppendSelection(clone.Find("body").Children()) + return root +} + +func layout(filename string, config config.Config, pageTitle string, pageURL string) (*goquery.Document, error) { html, err := loadTemplate(filename) if err != nil { return nil, err @@ -48,13 +101,22 @@ func layout(filename string, config config.Config, pageTitle string) (*goquery.D assetsOnce.Do(func() { var bytes []byte bytes, err = os.ReadFile("templates/style.css") + if err != nil { + return + } css = string(bytes) + countFile, err := os.OpenFile("templates/count.html", os.O_RDONLY, 0) + if err != nil { + return + } + defer countFile.Close() + countHTML, err = NewDocumentNoScript(countFile) }) if err != nil { return nil, err } - doc, err := goquery.NewDocumentFromReader(html) + doc, err := NewDocumentFromReader(html) if err != nil { return nil, err } @@ -63,17 +125,18 @@ func layout(filename string, config config.Config, pageTitle string) (*goquery.D doc.Find(".title").SetText(config.Title) doc.Find("title").Add(".p-name").SetText(pageTitle) doc.Find("head > style").SetHtml("\n" + string(css)) + doc.Find("body").setImgURL(pageURL, pageTitle) nav := doc.Find("nav") navLink := doc.Find("nav a") nav.Empty() for _, link := range config.Menus["main"] { nav.AppendSelection(navLink.Clone().SetAttr("href", link.URL).SetText(link.Name)) } - return doc, nil + return doc.Document, nil } func renderPost(post Post, config config.Config) (r io.Reader, err error) { - doc, err := layout("templates/post.html", config, post.PostMatter.Title) + doc, err := layout("templates/post.html", config, post.PostMatter.Title, post.URL) if err != nil { return nil, err } @@ -96,8 +159,8 @@ func renderPost(post Post, config config.Config) (r io.Reader, err error) { return renderHTML(doc), nil } -func renderTags(tags Tags, config config.Config) (io.Reader, error) { - doc, err := layout("templates/tags.html", config, config.Title) +func renderTags(tags Tags, config config.Config, url string) (io.Reader, error) { + doc, err := layout("templates/tags.html", config, config.Title, url) if err != nil { return nil, err } @@ -112,14 +175,14 @@ func renderTags(tags Tags, config config.Config) (io.Reader, error) { return renderHTML(doc), nil } -func renderListPage(tag string, config config.Config, posts []Post) (io.Reader, error) { +func renderListPage(tag string, config config.Config, posts []Post, url string) (io.Reader, error) { var title string if len(tag) > 0 { title = tag } else { title = config.Title } - doc, err := layout("templates/list.html", config, title) + doc, err := layout("templates/list.html", config, title, url) if err != nil { return nil, err } @@ -146,12 +209,12 @@ func renderListPage(tag string, config config.Config, posts []Post) (io.Reader, return renderHTML(doc), nil } -func renderHomepage(config config.Config, posts []Post) (io.Reader, error) { +func renderHomepage(config config.Config, posts []Post, url string) (io.Reader, error) { _, index, err := getPost("content/_index.md") if err != nil { return nil, err } - doc, err := layout("templates/homepage.html", config, config.Title) + doc, err := layout("templates/homepage.html", config, config.Title, url) if err != nil { return nil, err } @@ -193,8 +256,8 @@ func renderHomepage(config config.Config, posts []Post) (io.Reader, error) { return renderHTML(doc), nil } -func render404(config config.Config) (io.Reader, error) { - doc, err := layout("templates/404.html", config, "404 Not Found") +func render404(config config.Config, url string) (io.Reader, error) { + doc, err := layout("templates/404.html", config, "404 Not Found", url) if err != nil { return nil, err } |