diff options
| author | 2025-10-28 23:15:23 +0700 | |
|---|---|---|
| committer | 2025-10-28 23:15:23 +0700 | |
| commit | bda4faeeed4d9859cfe8afd7952a751683d74bd8 (patch) | |
| tree | 464c18fed0c21b63b65425f48a3a790229461058 /internal/router/handlers/lang-blog-title.go | |
| parent | dd69b45d3a41be2b5c38892c3b107770a0f859f2 (diff) | |
| parent | 1862f232eb70105340a91e74a5630c233a411bca (diff) | |
| download | web-0.11.1.tar.gz web-0.11.1.zip | |
v0.11.1 (#18)v0.11.1
- refactor: make structurized implementation of routes + separate
identity of router
- feat: update go to 1.25
- feat: update all dependencies
- debug: display routes when debug logs turned on
Diffstat (limited to 'internal/router/handlers/lang-blog-title.go')
| -rw-r--r-- | internal/router/handlers/lang-blog-title.go | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go new file mode 100644 index 0000000..f1be2cd --- /dev/null +++ b/internal/router/handlers/lang-blog-title.go @@ -0,0 +1,113 @@ +package handlers + +import ( + "bytes" + "fmt" + "html/template" + "strings" + "time" + + "github.com/SayaAndy/saya-today-web/internal/b2" + "github.com/SayaAndy/saya-today-web/internal/frontmatter" + "github.com/SayaAndy/saya-today-web/internal/router" + "github.com/gofiber/fiber/v2" + "github.com/yuin/goldmark" +) + +func init() { + router.Routes = append(router.Routes, &BlogPageHandler{}) +} + +type BlogPageHandler struct { + router.BasicHandler +} + +func (r *BlogPageHandler) Filter() (method string, path string) { + return "GET", "/:lang/blog/:title" +} + +func (r *BlogPageHandler) IsTemplated() bool { + return true +} + +func (r *BlogPageHandler) TemplatesToInject() []string { + return []string{"views/pages/blog-page.html"} +} + +func (r *BlogPageHandler) ToCache() router.CacheSetting { + return router.ByUrlOnly +} + +func (r *BlogPageHandler) CacheDuration() time.Duration { + return 15 * time.Minute +} + +func (r *BlogPageHandler) ToValidateLang() router.LangSetting { + return router.InPath +} + +func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { + _, pathParts, _, err := router.GetPathFromReferer(c) + if err != nil { + return fiber.StatusBadRequest, fmt.Errorf("failed to get path from referer: %w", err) + } + + metadata, parsedMarkdown, err := readBlogPost(supplements.MarkdownRenderer, supplements.B2Client, lang+"/"+pathParts[2]) + if err != nil { + return fiber.StatusNotFound, fmt.Errorf("failed to find '%s' post: %w", pathParts[2], err) + } + + geolocationParts := strings.Split(metadata.Geolocation, " ") + var x, y, areaError string + if len(geolocationParts) >= 2 { + x = geolocationParts[0] + y = geolocationParts[1] + } + if len(geolocationParts) >= 3 { + areaError = geolocationParts[2] + } + + templateMap["MapLocationX"] = x + templateMap["MapLocationY"] = y + templateMap["MapLocationAreaMeters"] = areaError + templateMap["Title"] = metadata.Title + templateMap["ParsedMarkdown"] = template.HTML(parsedMarkdown) + templateMap["PublishedDate"] = metadata.PublishedTime.Format("2006-01-02 15:04:05 -07:00") + templateMap["ActionDate"] = metadata.ActionDate + + go supplements.ClientCache.View(c.IP(), pathParts[2]) + + return fiber.StatusOK, nil +} + +func (r *BlogPageHandler) RenderHeader(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { + path, pathParts, _, err := router.GetPathFromReferer(c) + if err != nil { + return fiber.StatusBadRequest, fmt.Errorf("failed to get path from referer: %w", err) + } + + metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + pathParts[2] + ".md") + if err != nil { + return fiber.StatusNotFound, fmt.Errorf("could not read '%s' for metadata: %w", path, err) + } + + templateMap["Title"] = metadata.Title + templateMap["PublishedDate"] = metadata.PublishedTime.Format("2006-01-02 15:04:05 -07:00") + templateMap["ActionDate"] = metadata.ActionDate + + return fiber.StatusOK, nil +} + +func readBlogPost(md goldmark.Markdown, b2Client *b2.B2Client, sourceName string) (metadata *frontmatter.Metadata, html string, err error) { + metadata, markdown, err := b2Client.ReadFrontmatter(sourceName + ".md") + if err != nil { + return nil, "", fmt.Errorf("failed to read a frontmatter file: %w", err) + } + + var buf bytes.Buffer + if err := md.Convert(markdown, &buf); err != nil { + return nil, "", fmt.Errorf("convert source context from md to html: %w", err) + } + + return metadata, buf.String(), nil +} |