1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
package router
import (
"bytes"
"fmt"
"html/template"
"log/slog"
"strconv"
"strings"
"github.com/SayaAndy/saya-today-web/config"
"github.com/SayaAndy/saya-today-web/internal/b2"
"github.com/SayaAndy/saya-today-web/internal/frontmatter"
"github.com/SayaAndy/saya-today-web/locale"
"github.com/gofiber/fiber/v2"
"github.com/yuin/goldmark"
)
func init() {
tm.Add("blog-page", "views/layouts/general-page.html", "views/pages/blog-page.html")
}
func Lang_Blog_Title(l map[string]*locale.LocaleConfig, langs []config.AvailableLanguageConfig, b2Client *b2.B2Client, md goldmark.Markdown) func(c *fiber.Ctx) error {
return func(c *fiber.Ctx) error {
ip := c.IP()
slog.Debug("client entering blog page", slog.String("ip", ip), slog.String("page", c.Path()))
lang := c.Params("lang")
for _, availableLang := range langs {
if availableLang.Name == lang {
goto langIsAvailable
}
}
return c.Status(fiber.ErrNotFound.Code).SendString(fmt.Sprintf("server does not support '%s' language", lang))
langIsAvailable:
metadata, parsedMarkdown, err := readBlogPost(md, b2Client, lang+"/"+c.Params("title"))
if err != nil {
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
return c.Status(fiber.ErrNotFound.Code).SendString(fmt.Sprintf("failed to find '%s' post", c.Params("title")))
}
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]
}
content, err := tm.Render("blog-page", fiber.Map{
"Title": metadata.Title,
"PublishedDate": metadata.PublishedTime.Format("2006-01-02 15:04:05 -07:00"),
"PublishedYear": strconv.Itoa(metadata.PublishedTime.Year()),
"ParsedMarkdown": template.HTML(parsedMarkdown),
"MapLocationX": x,
"MapLocationY": y,
"MapLocationAreaMeters": areaError,
"Lang": lang,
"QueryString": string(c.Request().URI().QueryString()),
})
if err != nil {
slog.Warn("failed to generate page", slog.String("page", "/"+lang+"/blog/"+c.Params("title")), slog.String("error", err.Error()))
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate page")
}
return c.Type("html").Send(content)
}
}
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
}
|