Started working on pages
This commit is contained in:
parent
e2f159e980
commit
ba12398d2f
30 changed files with 1391 additions and 145 deletions
105
services/sitebuilder/pages.go
Normal file
105
services/sitebuilder/pages.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
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)
|
||||
}
|
||||
|
||||
if err := s.writePage(site, themeMeta, bundle, 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
|
||||
}
|
||||
|
||||
postFilename := s.pageFilename(site, bundle, 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 })
|
||||
|
||||
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(site, themeMeta, bundlesByID[page.BundleID], page); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
startId = pages[len(pages)-1].ID
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) writePage(site models.Site, themeMeta models.ThemeMeta, bundle models.Bundle, page models.Page) error {
|
||||
postFilename := s.pageFilename(site, bundle, page)
|
||||
|
||||
frontMatter := map[string]any{
|
||||
"date": page.PublishDate.Format(time.RFC3339),
|
||||
}
|
||||
if page.Title != "" {
|
||||
frontMatter["title"] = page.Title
|
||||
} else if themeMeta.PreferTitle {
|
||||
frontMatter["title"] = page.PublishDate.Format(time.ANSIC)
|
||||
}
|
||||
|
||||
return s.writeMarkdownFile(postFilename, frontMatter, page.Body)
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"gopkg.in/yaml.v3"
|
||||
"lmika.dev/lmika/hugo-cms/models"
|
||||
"lmika.dev/lmika/hugo-cms/providers/hugo"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
|
@ -104,19 +103,21 @@ func (s *Service) writePost(site models.Site, post models.Post) error {
|
|||
|
||||
postFilename := s.postFilename(site, themeMeta, post)
|
||||
|
||||
log.Printf(" .. post %v", postFilename)
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(postFilename), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frontMatter := map[string]string{
|
||||
"date": post.PostDate.Format(time.RFC3339),
|
||||
frontMatter := map[string]any{
|
||||
"date": post.PublishDate.Format(time.RFC3339),
|
||||
}
|
||||
if post.Title != "" {
|
||||
frontMatter["title"] = post.Title
|
||||
} else if themeMeta.PreferTitle {
|
||||
frontMatter["title"] = post.PostDate.Format(time.ANSIC)
|
||||
frontMatter["title"] = post.PublishDate.Format(time.ANSIC)
|
||||
}
|
||||
|
||||
return s.writeMarkdownFile(postFilename, frontMatter, post.Body)
|
||||
}
|
||||
|
||||
func (s *Service) writeMarkdownFile(outFile string, frontMatter map[string]any, body string) error {
|
||||
if err := os.MkdirAll(filepath.Dir(outFile), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmBytes, err := yaml.Marshal(frontMatter)
|
||||
|
|
@ -124,7 +125,7 @@ func (s *Service) writePost(site models.Site, post models.Post) error {
|
|||
return err
|
||||
}
|
||||
|
||||
f, err := os.Create(postFilename)
|
||||
f, err := os.Create(outFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -139,7 +140,7 @@ func (s *Service) writePost(site models.Site, post models.Post) error {
|
|||
if _, err := f.WriteString("---\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.WriteString(post.Body); err != nil {
|
||||
if _, err := f.WriteString(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -147,5 +148,15 @@ func (s *Service) writePost(site models.Site, post models.Post) error {
|
|||
}
|
||||
|
||||
func (s *Service) postFilename(site models.Site, themeMeta models.ThemeMeta, post models.Post) string {
|
||||
return filepath.Join(s.hugo.SiteStagingDir(site, hugo.ContentSiteDir), themeMeta.PostDir, post.CreatedAt.Format("2006-01-02-150405.md"))
|
||||
return filepath.Join(s.hugo.SiteStagingDir(site, hugo.ContentSiteDir), themeMeta.BlogPostBundle, post.CreatedAt.Format("2006-01-02-150405.md"))
|
||||
}
|
||||
|
||||
func (s *Service) pageFilename(site models.Site, bundle models.Bundle, page models.Page) string {
|
||||
bundleDir := ""
|
||||
if bundle.Name != models.RootBundleName {
|
||||
bundleDir = bundle.Name
|
||||
}
|
||||
|
||||
pageName := page.Name + ".md"
|
||||
return filepath.Join(s.hugo.SiteStagingDir(site, hugo.ContentSiteDir), bundleDir, pageName)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ func (s *Service) rebuildSite(ctx context.Context, oldSite, newSite models.Site)
|
|||
return err
|
||||
}
|
||||
|
||||
if err := s.writeAllPages(ctx, newSite); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.publish(ctx, newSite)
|
||||
}
|
||||
|
||||
|
|
@ -148,3 +152,4 @@ func (s *Service) signalSiteBuildingStarted(ctx context.Context, site models.Sit
|
|||
func (s *Service) signalSiteBuildingFinished(ctx context.Context, site models.Site) {
|
||||
s.bus.Fire(models.Event{Type: models.EventSiteBuildingDone, Data: site})
|
||||
}
|
||||
|
||||
|
|
|
|||
32
services/sitebuilder/tracker.go
Normal file
32
services/sitebuilder/tracker.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package sitebuilder
|
||||
|
||||
import (
|
||||
"lmika.dev/lmika/hugo-cms/models"
|
||||
"lmika.dev/lmika/hugo-cms/providers/bus"
|
||||
)
|
||||
|
||||
type SiteBuildingTracker struct {
|
||||
bus *bus.Bus
|
||||
isBuildingState map[int64]models.Site
|
||||
}
|
||||
|
||||
func NewSiteBuildingTracker(bus *bus.Bus) *SiteBuildingTracker {
|
||||
return &SiteBuildingTracker{
|
||||
bus: bus,
|
||||
isBuildingState: map[int64]models.Site{},
|
||||
}
|
||||
}
|
||||
|
||||
func (sbt *SiteBuildingTracker) Listen() {
|
||||
sub := sbt.bus.Subscribe()
|
||||
|
||||
for e := range sub.C {
|
||||
switch e.Type {
|
||||
case models.EventSiteBuildingStart:
|
||||
site := e.Data.(models.Site)
|
||||
sbt.isBuildingState[site.ID] = site
|
||||
case models.EventSiteBuildingDone:
|
||||
delete(sbt.isBuildingState, e.Data.(models.Site).ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue