103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
// internal/article/load.go
|
||
package article
|
||
|
||
// internal/article/load.go (gekürzt)
|
||
|
||
import (
|
||
"bufio"
|
||
"encoding/json"
|
||
"fmt"
|
||
"html/template"
|
||
"io"
|
||
"io/fs"
|
||
"os"
|
||
"path/filepath"
|
||
"sort"
|
||
"strings"
|
||
"time"
|
||
|
||
md "github.com/gomarkdown/markdown"
|
||
"github.com/gomarkdown/markdown/html"
|
||
"github.com/gomarkdown/markdown/parser"
|
||
)
|
||
|
||
func LoadDir(root string) ([]Article, error) {
|
||
var out []Article
|
||
|
||
// gültige Extension‑Maske
|
||
exts := parser.CommonExtensions | parser.AutoHeadingIDs | parser.DefinitionLists
|
||
mdRenderer := html.NewRenderer(html.RendererOptions{
|
||
Flags: html.CommonFlags | html.HrefTargetBlank,
|
||
})
|
||
|
||
err := filepath.WalkDir(root, func(p string, d fs.DirEntry, err error) error {
|
||
if err != nil || d.IsDir() {
|
||
return err
|
||
}
|
||
|
||
ext := filepath.Ext(p)
|
||
if ext != ".html" && ext != ".md" {
|
||
return nil
|
||
}
|
||
|
||
f, err := os.Open(p)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer f.Close()
|
||
|
||
r := bufio.NewReader(f)
|
||
headerLine, err := r.ReadBytes('\n')
|
||
if err != nil && err != io.EOF {
|
||
return err
|
||
}
|
||
|
||
var meta struct {
|
||
Title string `json:"title"`
|
||
Date string `json:"date"`
|
||
Slug string `json:"slug"`
|
||
Cover string `json:"cover"` // NEW
|
||
}
|
||
clean := strings.TrimSpace(string(headerLine))
|
||
|
||
clean = strings.TrimPrefix(clean, "<!--")
|
||
clean = strings.TrimSpace(clean)
|
||
|
||
// alles nach dem ersten "-->" abschneiden (egal ob Leerzeichen davor)
|
||
if idx := strings.Index(clean, "-->"); idx != -1 {
|
||
clean = clean[:idx]
|
||
}
|
||
clean = strings.TrimSpace(clean)
|
||
|
||
if err := json.Unmarshal([]byte(clean), &meta); err != nil {
|
||
return fmt.Errorf("Front‑Matter in %s: %w (%q)", p, err, clean)
|
||
}
|
||
|
||
bodyBytes, err := io.ReadAll(r)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
htmlBody := bodyBytes
|
||
if ext == ".md" {
|
||
mdParser := parser.NewWithExtensions(exts)
|
||
htmlBody = md.ToHTML(bodyBytes, mdParser, mdRenderer)
|
||
}
|
||
|
||
date, err := time.Parse("2006-01-02", meta.Date)
|
||
if err != nil {
|
||
fmt.Println("Time", err, date)
|
||
}
|
||
out = append(out, Article{
|
||
Title: meta.Title,
|
||
Slug: meta.Slug,
|
||
Date: date,
|
||
Cover: meta.Cover, // NEW
|
||
Body: template.HTML(htmlBody),
|
||
})
|
||
return nil
|
||
})
|
||
sort.Slice(out, func(i, j int) bool { return out[i].Date.After(out[j].Date) })
|
||
return out, err
|
||
}
|