From bbfe6055609c4e7401f27d3dd4a5aa9c0a5242d6 Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Wed, 24 Apr 2024 18:01:15 +0200 Subject: add count --- cmd/build/build.go | 10 +++--- cmd/build/template.go | 87 ++++++++++++++++++++++++++++++++++++++++++++------- config.toml | 2 +- templates/count.html | 6 ++++ 4 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 templates/count.html diff --git a/cmd/build/build.go b/cmd/build/build.go index 9b58095..21eedbd 100644 --- a/cmd/build/build.go +++ b/cmd/build/build.go @@ -78,7 +78,7 @@ func build(outDir string, config config.Config) error { return errors.WithMessage(err, "could not create directory for tags") } slog.Debug("rendering tags list") - output, err := renderTags(tags, config) + output, err := renderTags(tags, config, "/tags") if err != nil { return errors.WithMessage(err, "could not render tags") } @@ -97,7 +97,7 @@ func build(outDir string, config config.Config) error { return errors.WithMessage(err, "could not create directory") } slog.Debug("rendering tags page", "tag", tag) - output, err := renderListPage(tag, config, matchingPosts) + output, err := renderListPage(tag, config, matchingPosts, "/tags/"+tag) if err != nil { return errors.WithMessage(err, "could not render tag page") } @@ -116,7 +116,7 @@ func build(outDir string, config config.Config) error { } slog.Debug("rendering list page") - listPage, err := renderListPage("", config, posts) + listPage, err := renderListPage("", config, posts, "/post") if err != nil { return errors.WithMessage(err, "could not render list page") } @@ -143,7 +143,7 @@ func build(outDir string, config config.Config) error { } slog.Debug("rendering homepage") - homePage, err := renderHomepage(config, posts) + homePage, err := renderHomepage(config, posts, "/") if err != nil { return errors.WithMessage(err, "could not render homepage") } @@ -152,7 +152,7 @@ func build(outDir string, config config.Config) error { } slog.Debug("rendering 404 page") - notFound, err := render404(config) + notFound, err := render404(config, "/404.html") if err != nil { return errors.WithMessage(err, "could not render 404 page") } 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(" 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 } diff --git a/config.toml b/config.toml index 067b829..e79653d 100644 --- a/config.toml +++ b/config.toml @@ -16,7 +16,7 @@ feed = true [extra.headers] cache-control = "max-age=14400" x-content-type-options = "nosniff" -content-security-policy = "default-src 'none'; img-src 'self'; object-src 'none'; script-src 'self'; style-src 'unsafe-inline'; form-action 'none'; base-uri 'self'; frame-ancestors https://kagi.com;" +content-security-policy = "default-src 'none'; img-src 'self' https://gc.zgo.at; script-src 'self https://gc.zgo.at'; style-src 'unsafe-inline'; frame-ancestors https://kagi.com; connect-src https://alanpearce-eu.goatcounter.com/count; require-trusted-types-for 'script'" [[menus.main]] name = "Home" diff --git a/templates/count.html b/templates/count.html new file mode 100644 index 0000000..737b99d --- /dev/null +++ b/templates/count.html @@ -0,0 +1,6 @@ + + + + -- cgit 1.4.1