tijl.dev-core/internal/handlers/blog.go
tijl d77d2cc94c
All checks were successful
build / build (push) Successful in 51s
web changes + blog implementation
2024-08-22 18:04:08 +02:00

143 lines
3.4 KiB
Go

package handlers
// blog implementation concept
import (
"bytes"
"fmt"
"os"
"path/filepath"
"time"
"git.tijl.dev/tijl/tijl.dev-core/internal/i18n"
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
Content string
}
type PostMeta struct {
Title string
Slug string
Description string
Author string
Language string
PublishDate time.Time
UpdatedDate time.Time
Tags []string
}
var posts []Post
func LoadPosts() {
posts = []Post{}
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(),
),
)
files, err := filepath.Glob("blog/*.md")
if err != nil {
log.Error().Err(err).Msg("handlers.LoadPosts(): error reading folder")
}
for _, file := range files {
content, err := os.ReadFile(file)
if err != nil {
log.Error().Err(err).Msg("handlers.LoadPosts(): error reading file")
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)
posts = append(posts, Post{
Content: buf.String(),
Meta: postMeta,
})
}
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")
}
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")
}
if updatedDate, ok := m["updated_date"].(string); ok {
post.UpdatedDate, err = time.Parse("02 Jan 2006", updatedDate)
if err != nil {
return post, fmt.Errorf("invalid format for PublishDate: %v", err)
}
} else {
return post, fmt.Errorf("missing or invalid type for PublishDate")
}
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")
}
}
} else {
return post, fmt.Errorf("missing or invalid type for Tags")
}
return post, nil
}