diff options
Diffstat (limited to 'internal/builder')
-rw-r--r-- | internal/builder/builder.go | 35 | ||||
-rw-r--r-- | internal/builder/homepage.templ | 5 | ||||
-rw-r--r-- | internal/builder/list.templ | 11 | ||||
-rw-r--r-- | internal/builder/post.templ | 3 | ||||
-rw-r--r-- | internal/builder/posts.go | 129 | ||||
-rw-r--r-- | internal/builder/sitemap.go | 29 | ||||
-rw-r--r-- | internal/builder/template.go | 3 |
7 files changed, 25 insertions, 190 deletions
diff --git a/internal/builder/builder.go b/internal/builder/builder.go index 7b6af0b..141bd6f 100644 --- a/internal/builder/builder.go +++ b/internal/builder/builder.go @@ -11,13 +11,14 @@ import ( "time" "website/internal/config" + "website/internal/content" "website/internal/log" + "website/internal/sitemap" "github.com/a-h/templ" mapset "github.com/deckarep/golang-set/v2" cp "github.com/otiai10/copy" "github.com/pkg/errors" - "github.com/snabb/sitemap" ) type IOConfig struct { @@ -108,12 +109,12 @@ func build(outDir string, config config.Config) (*Result, error) { return nil, errors.WithMessage(err, "could not create post output directory") } log.Debug("reading posts") - posts, tags, err := readPosts("content", "post", publicDir) + posts, tags, err := content.ReadPosts("content", "post", publicDir) if err != nil { return nil, err } - sm := NewSitemap(config) + sitemap := sitemap.New(config) lastMod := time.Now() if len(posts) > 0 { lastMod = posts[0].Date @@ -124,10 +125,7 @@ func build(outDir string, config config.Config) (*Result, error) { return nil, errors.WithMessage(err, "could not create directory for post") } log.Debug("rendering post", "post", post.Basename) - sm.Add(&sitemap.URL{ - Loc: post.URL, - LastMod: &post.Date, - }) + sitemap.AddPath(post.URL, post.Date) if err := renderToFile(postPage(config, post), post.Output); err != nil { return nil, err } @@ -140,13 +138,10 @@ func build(outDir string, config config.Config) (*Result, error) { if err := renderToFile(tagsPage(config, "tags", mapset.Sorted(tags), "/tags"), publicDir, "tags", "index.html"); err != nil { return nil, err } - sm.Add(&sitemap.URL{ - Loc: "/tags/", - LastMod: &lastMod, - }) + sitemap.AddPath("/tags/", lastMod) for _, tag := range tags.ToSlice() { - matchingPosts := []Post{} + matchingPosts := []content.Post{} for _, post := range posts { if slices.Contains(post.Taxonomies.Tags, tag) { matchingPosts = append(matchingPosts, post) @@ -160,10 +155,7 @@ func build(outDir string, config config.Config) (*Result, error) { if err := renderToFile(tagPage(config, tag, matchingPosts, url), publicDir, "tags", tag, "index.html"); err != nil { return nil, err } - sm.Add(&sitemap.URL{ - Loc: url, - LastMod: &matchingPosts[0].Date, - }) + sitemap.AddPath(url, matchingPosts[0].Date) log.Debug("rendering tags feed", "tag", tag) feed, err := renderFeed( @@ -184,10 +176,7 @@ func build(outDir string, config config.Config) (*Result, error) { if err := renderToFile(listPage(config, posts, "/post"), publicDir, "post", "index.html"); err != nil { return nil, err } - sm.Add(&sitemap.URL{ - Loc: "/post/", - LastMod: &lastMod, - }) + sitemap.AddPath("/post/", lastMod) log.Debug("rendering feed") feed, err := renderFeed(config.Title, config, posts, "feed") @@ -223,9 +212,7 @@ func build(outDir string, config config.Config) (*Result, error) { // it would be nice to set LastMod here, but using the latest post // date would be wrong as the homepage has its own content file // without a date, which could be newer - sm.Add(&sitemap.URL{ - Loc: "/", - }) + sitemap.AddPath("/", time.Time{}) h, _ = getHTMLStyleHash(publicDir, "index.html") r.Hashes = append(r.Hashes, h) @@ -235,7 +222,7 @@ func build(outDir string, config config.Config) (*Result, error) { } log.Debug("rendering sitemap") - if err := writerToFile(sm, publicDir, "sitemap.xml"); err != nil { + if err := writerToFile(sitemap, publicDir, "sitemap.xml"); err != nil { return nil, err } diff --git a/internal/builder/homepage.templ b/internal/builder/homepage.templ index 9897b5d..1df401b 100644 --- a/internal/builder/homepage.templ +++ b/internal/builder/homepage.templ @@ -3,11 +3,12 @@ package builder import ( "website/internal/config" "path" + "website/internal/content" ) func getContent(filename string) templ.Component { return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error { - _, index, err := getPost(path.Join("content", filename)) + _, index, err := content.GetPost(path.Join("content", filename)) if err != nil { return err } @@ -17,7 +18,7 @@ func getContent(filename string) templ.Component { }) } -templ homepage(config config.Config, posts []Post) { +templ homepage(config config.Config, posts []content.Post) { @page(config, PageSettings{ Title: config.Title, TitleAttrs: templ.Attributes{ diff --git a/internal/builder/list.templ b/internal/builder/list.templ index 48563ed..24cafe8 100644 --- a/internal/builder/list.templ +++ b/internal/builder/list.templ @@ -1,8 +1,11 @@ package builder -import "website/internal/config" +import ( + "website/internal/config" + "website/internal/content" +) -templ tagPage(config config.Config, tag string, posts []Post, path string) { +templ tagPage(config config.Config, tag string, posts []content.Post, path string) { @page(config, PageSettings{ Title: tag, Path: path, @@ -21,7 +24,7 @@ templ tagPage(config config.Config, tag string, posts []Post, path string) { } } -templ listPage(config config.Config, posts []Post, path string) { +templ listPage(config config.Config, posts []content.Post, path string) { @page(config, PageSettings{ Title: config.Title, TitleAttrs: templ.Attributes{ @@ -34,7 +37,7 @@ templ listPage(config config.Config, posts []Post, path string) { } } -templ list(posts []Post) { +templ list(posts []content.Post) { <ul class="h-feed"> for _, post := range posts { <li class="h-entry"> diff --git a/internal/builder/post.templ b/internal/builder/post.templ index 740c5aa..6f12e5c 100644 --- a/internal/builder/post.templ +++ b/internal/builder/post.templ @@ -3,6 +3,7 @@ package builder import ( "time" "website/internal/config" + "website/internal/content" ) func Unsafe(html string) templ.Component { @@ -18,7 +19,7 @@ templ postDate(d time.Time) { </time> } -templ postPage(config config.Config, post Post) { +templ postPage(config config.Config, post content.Post) { @page(config, PageSettings{ Title: post.Title, TitleAttrs: templ.Attributes{ diff --git a/internal/builder/posts.go b/internal/builder/posts.go deleted file mode 100644 index deae3e8..0000000 --- a/internal/builder/posts.go +++ /dev/null @@ -1,129 +0,0 @@ -package builder - -import ( - "bytes" - "os" - "path" - "path/filepath" - "slices" - "strings" - "time" - "website/internal/log" - - "github.com/adrg/frontmatter" - mapset "github.com/deckarep/golang-set/v2" - "github.com/pkg/errors" - fences "github.com/stefanfritsch/goldmark-fences" - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/extension" - htmlrenderer "github.com/yuin/goldmark/renderer/html" -) - -type PostMatter struct { - Date time.Time `toml:"date"` - Description string `toml:"description"` - Title string `toml:"title"` - Taxonomies struct { - Tags []string `toml:"tags"` - } `toml:"taxonomies"` -} - -type Post struct { - Input string - Output string - Basename string - URL string - Content string - PostMatter -} - -type Tags mapset.Set[string] - -var markdown = goldmark.New( - goldmark.WithRendererOptions( - htmlrenderer.WithUnsafe(), - ), - goldmark.WithExtensions( - extension.GFM, - extension.Footnote, - extension.Typographer, - &fences.Extender{}, - ), -) - -func getPost(filename string) (*PostMatter, []byte, error) { - matter := PostMatter{} - content, err := os.Open(filename) - if err != nil { - return nil, nil, errors.WithMessagef(err, "could not open post %s", filename) - } - defer content.Close() - rest, err := frontmatter.MustParse(content, &matter) - if err != nil { - return nil, nil, errors.WithMessagef( - err, - "could not parse front matter of post %s", - filename, - ) - } - - return &matter, rest, nil -} - -func renderMarkdown(content []byte) (string, error) { - var buf bytes.Buffer - if err := markdown.Convert(content, &buf); err != nil { - return "", errors.WithMessage(err, "could not convert markdown content") - } - - return buf.String(), nil -} - -func readPosts(root string, inputDir string, outputDir string) ([]Post, Tags, error) { - tags := mapset.NewSet[string]() - posts := []Post{} - subdir := filepath.Join(root, inputDir) - files, err := os.ReadDir(subdir) - if err != nil { - return nil, nil, errors.WithMessagef(err, "could not read post directory %s", subdir) - } - outputReplacer := strings.NewReplacer(root, outputDir, ".md", "/index.html") - urlReplacer := strings.NewReplacer(root, "", ".md", "/") - for _, f := range files { - pathFromRoot := filepath.Join(subdir, f.Name()) - if !f.IsDir() && path.Ext(pathFromRoot) == ".md" { - output := outputReplacer.Replace(pathFromRoot) - url := urlReplacer.Replace(pathFromRoot) - log.Debug("reading post", "post", pathFromRoot) - matter, content, err := getPost(pathFromRoot) - if err != nil { - return nil, nil, err - } - - for _, tag := range matter.Taxonomies.Tags { - tags.Add(strings.ToLower(tag)) - } - - log.Debug("rendering markdown in post", "post", pathFromRoot) - html, err := renderMarkdown(content) - if err != nil { - return nil, nil, err - } - post := Post{ - Input: pathFromRoot, - Output: output, - Basename: filepath.Base(url), - URL: url, - PostMatter: *matter, - Content: html, - } - - posts = append(posts, post) - } - } - slices.SortFunc(posts, func(a, b Post) int { - return b.Date.Compare(a.Date) - }) - - return posts, tags, nil -} diff --git a/internal/builder/sitemap.go b/internal/builder/sitemap.go deleted file mode 100644 index 81e3a31..0000000 --- a/internal/builder/sitemap.go +++ /dev/null @@ -1,29 +0,0 @@ -package builder - -import ( - "io" - "website/internal/config" - - "github.com/snabb/sitemap" -) - -type Sitemap struct { - config *config.Config - Sitemap *sitemap.Sitemap -} - -func NewSitemap(cfg config.Config) *Sitemap { - return &Sitemap{ - config: &cfg, - Sitemap: sitemap.New(), - } -} - -func (s *Sitemap) Add(u *sitemap.URL) { - u.Loc = s.config.BaseURL.JoinPath(u.Loc).String() - s.Sitemap.Add(u) -} - -func (s *Sitemap) WriteTo(w io.Writer) (int64, error) { - return s.Sitemap.WriteTo(w) -} diff --git a/internal/builder/template.go b/internal/builder/template.go index 376e48a..9b1d9bd 100644 --- a/internal/builder/template.go +++ b/internal/builder/template.go @@ -9,6 +9,7 @@ import ( "text/template" "website/internal/atom" "website/internal/config" + "website/internal/content" "website/internal/log" "github.com/PuerkitoBio/goquery" @@ -89,7 +90,7 @@ func renderRobotsTXT(config config.Config) (io.Reader, error) { func renderFeed( title string, config config.Config, - posts []Post, + posts []content.Post, specific string, ) (io.Reader, error) { reader, err := loadTemplate("templates/feed.xml") |