hugo-cms/services/sitebuilder/pages.go
Leon Mika 68aa9c0e13 Added site previewing
This will generate a local version of the Hugo site and serve it via the server
2025-02-17 21:41:36 +11:00

147 lines
3.2 KiB
Go

package sitebuilder
import (
"context"
"fmt"
"lmika.dev/lmika/hugo-cms/models"
"lmika.dev/pkg/modash/momap"
"os"
"time"
)
func (s *Service) WritePage(site models.Site, bundle models.Bundle, page models.Page) models.Job {
return models.Job{
Do: func(ctx context.Context) error {
s.signalSiteBuildingStarted(ctx, site)
defer s.signalSiteBuildingFinished(ctx, site)
rbn, err := s.fullRebuildNecessary(ctx, site)
if err != nil {
return err
} else if rbn {
return s.rebuildSite(ctx, site, site)
}
themeMeta, ok := s.themes.Lookup(site.Theme)
if !ok {
return fmt.Errorf("theme %s not found in themes", site.Theme)
}
bundleInfo, err := s.db.GetSiteBundleInfo(ctx, site.ID)
if err != nil {
return err
}
if err := s.writePage(pageBuildInfo{
site: site,
themeMeta: themeMeta,
bundle: bundle,
bundleInfo: bundleInfo,
}, page); err != nil {
return err
}
return s.publish(ctx, site)
},
}
}
func (s *Service) DeletePage(site models.Site, page models.Page) models.Job {
return models.Job{
Do: func(ctx context.Context) error {
s.signalSiteBuildingStarted(ctx, site)
defer s.signalSiteBuildingFinished(ctx, site)
bundle, err := s.db.GetBundleWithID(ctx, page.BundleID)
if err != nil {
return err
}
themeMeta, ok := s.themes.Lookup(site.Theme)
if !ok {
return fmt.Errorf("theme %s not found in themes", site.Theme)
}
bundleInfo, err := s.db.GetSiteBundleInfo(ctx, site.ID)
if err != nil {
return err
}
postFilename := s.pageFilename(pageBuildInfo{
site: site,
themeMeta: themeMeta,
bundle: bundle,
bundleInfo: bundleInfo,
}, page)
if os.Remove(postFilename) != nil {
return nil
}
// TODO: if dir is empty, delete it
return s.publish(ctx, site)
},
}
}
func (s *Service) writeAllPages(ctx context.Context, site models.Site) error {
themeMeta, ok := s.themes.Lookup(site.Theme)
if !ok {
return fmt.Errorf("theme %s not found in themes", site.Theme)
}
bundles, err := s.db.ListBundles(ctx, site.ID)
if err != nil {
return err
}
bundlesByID := momap.FromSlice(bundles, func(b models.Bundle) (int64, models.Bundle) { return b.ID, b })
bundleInfo, err := s.db.GetSiteBundleInfo(ctx, site.ID)
if err != nil {
return err
}
var startId int64
for {
pages, err := s.db.ListPublishablePages(ctx, int64(startId), site.ID)
if err != nil {
return err
} else if len(pages) == 0 {
return nil
}
for _, page := range pages {
if err := s.writePage(pageBuildInfo{
site: site,
themeMeta: themeMeta,
bundle: bundlesByID[page.BundleID],
bundleInfo: bundleInfo,
}, page); err != nil {
return err
}
}
startId = pages[len(pages)-1].ID
}
}
func (s *Service) writePage(bi pageBuildInfo, page models.Page) error {
postFilename := s.pageFilename(bi, page)
frontMatter := map[string]any{
"date": page.PublishDate.Format(time.RFC3339),
}
if page.Title != "" {
frontMatter["title"] = page.Title
}
return s.writeMarkdownFile(postFilename, frontMatter, page.Body)
}
type pageBuildInfo struct {
site models.Site
themeMeta models.ThemeMeta
bundle models.Bundle
bundleInfo map[int64]models.BundleInfo
}