tijl.dev-core/internal/handlers/blog.go

156 lines
3.8 KiB
Go
Raw Permalink Normal View History

2024-08-22 18:04:08 +02:00
package handlers
// blog implementation concept
import (
"bytes"
"fmt"
2024-08-22 20:28:21 +02:00
"html/template"
2024-08-22 18:04:08 +02:00
"os"
"path/filepath"
"time"
2024-08-29 12:21:38 +02:00
"git.tijl.dev/tijl/tijl.dev-core/internal/config"
2024-08-24 17:48:14 +02:00
"git.tijl.dev/tijl/tijl.dev-core/modules/i18n"
2024-08-22 18:04:08 +02:00
log "git.tijl.dev/tijl/tijl.dev-core/modules/logger"
"git.tijl.dev/tijl/tijl.dev-core/modules/web"
"github.com/gofiber/fiber/v2"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
)
type Post struct {
Meta PostMeta
2024-08-22 20:28:21 +02:00
Content template.HTML
2024-08-22 18:04:08 +02:00
}
type PostMeta struct {
Title string
Slug string
Description string
Author string
Language string
PublishDate time.Time
UpdatedDate time.Time
Tags []string
}
2024-08-22 20:28:21 +02:00
var posts map[string]Post
2024-08-22 18:04:08 +02:00
func LoadPosts() {
2024-08-22 20:28:21 +02:00
posts = map[string]Post{}
2024-08-22 18:04:08 +02:00
md := goldmark.New(
goldmark.WithExtensions(extension.Table, extension.Strikethrough, extension.Linkify, extension.TaskList, extension.GFM, extension.DefinitionList, extension.Footnote, extension.Typographer, meta.Meta),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
)
2024-08-29 12:21:38 +02:00
files, err := filepath.Glob(filepath.Join(config.Config.DataLocation, "blog/*.md"))
2024-08-22 18:04:08 +02:00
if err != nil {
2024-08-22 20:28:21 +02:00
log.Error().Err(err).Msg("error reading folder")
2024-08-22 18:04:08 +02:00
}
for _, file := range files {
content, err := os.ReadFile(file)
if err != nil {
2024-08-22 20:28:21 +02:00
log.Error().Err(err).Msg(" error reading file")
2024-08-22 18:04:08 +02:00
continue
}
var buf bytes.Buffer
context := parser.NewContext()
if err := md.Convert(content, &buf, parser.WithContext(context)); err != nil {
log.Fatal().Err(err)
}
metaData := meta.Get(context)
postMeta, err := MapToPostMeta(metaData)
2024-08-22 20:28:21 +02:00
if err != nil {
log.Error().Err(err).Msg("error mapping interface to post meta")
continue
}
posts[postMeta.Slug] = Post{
Content: template.HTML(buf.String()),
2024-08-22 18:04:08 +02:00
Meta: postMeta,
2024-08-22 20:28:21 +02:00
}
2024-08-22 18:04:08 +02:00
}
log.Debug().Msg("loaded blog posts")
}
func blogIndexHandler(c *fiber.Ctx) error {
data := *web.Common(c)
data["Title"] = i18n.Translate(c, "blog")
data["Posts"] = posts
return c.Render("blog", data, "layouts/base")
}
2024-08-22 20:28:21 +02:00
func blogHandler(c *fiber.Ctx) error {
data := *web.Common(c)
data["Title"] = i18n.Translate(c, "blog")
post, ok := posts[c.Params("post")]
if !ok {
return c.Render("404", data, "layouts/base")
}
data["Post"] = post
return c.Render("post", data, "layouts/base")
}
2024-08-22 18:04:08 +02:00
func MapToPostMeta(m map[string]interface{}) (PostMeta, error) {
var post PostMeta
var ok bool
var err error
if post.Title, ok = m["title"].(string); !ok {
return post, fmt.Errorf("missing or invalid type for Title")
}
if post.Slug, ok = m["slug"].(string); !ok {
return post, fmt.Errorf("missing or invalid type for Title")
}
if post.Description, ok = m["description"].(string); !ok {
return post, fmt.Errorf("missing or invalid type for Description")
}
if post.Author, ok = m["author"].(string); !ok {
return post, fmt.Errorf("missing or invalid type for Author")
}
if post.Language, ok = m["language"].(string); !ok {
return post, fmt.Errorf("missing or invalid type for Language")
}
if publishDate, ok := m["publish_date"].(string); ok {
post.PublishDate, err = time.Parse("02 Jan 2006", publishDate)
if err != nil {
return post, fmt.Errorf("invalid format for PublishDate: %v", err)
}
} else {
return post, fmt.Errorf("missing or invalid type for PublishDate")
}
2024-08-22 20:28:21 +02:00
if updatedDate, ok := m["update_date"].(string); ok {
2024-08-22 18:04:08 +02:00
post.UpdatedDate, err = time.Parse("02 Jan 2006", updatedDate)
if err != nil {
2024-08-22 20:28:21 +02:00
return post, fmt.Errorf("invalid format for UpdatedDate: %v", err)
2024-08-22 18:04:08 +02:00
}
}
if tags, ok := m["tags"].([]interface{}); ok {
for _, tag := range tags {
if strTag, ok := tag.(string); ok {
post.Tags = append(post.Tags, strTag)
} else {
return post, fmt.Errorf("invalid type in Tags slice")
}
}
}
return post, nil
}