diff --git a/example-content/Creation of Repo.md b/example-content/Creation of Repo.md index 857a2a2..8923563 100644 --- a/example-content/Creation of Repo.md +++ b/example-content/Creation of Repo.md @@ -1,5 +1,5 @@ +++ -catagories = ["Events"] +categories = ["Events"] date = "2023-08-23" +++ diff --git a/example-content/Fogo.sh.md b/example-content/Fogo.sh.md index c283521..81d1a33 100644 --- a/example-content/Fogo.sh.md +++ b/example-content/Fogo.sh.md @@ -1,5 +1,5 @@ +++ -catagories = ["Groups"] +categories = ["Groups"] +++ The group / GitHub organization around [[Almanac]]. diff --git a/example-content/Jack.md b/example-content/Jack.md index 07ec645..a601dba 100644 --- a/example-content/Jack.md +++ b/example-content/Jack.md @@ -1,3 +1,3 @@ +++ -catagories = ["Contributors"] +categories = ["Contributors"] +++ diff --git a/example-content/Opening of Fogo Island Inn.md b/example-content/Opening of Fogo Island Inn.md index fe04206..0353fe1 100644 --- a/example-content/Opening of Fogo Island Inn.md +++ b/example-content/Opening of Fogo Island Inn.md @@ -1,5 +1,5 @@ +++ -catagories = ["Events"] +categories = ["Events"] date = "2023-06-25" +++ diff --git a/example-content/POBBLES - We Wish You.md b/example-content/POBBLES - We Wish You.md index c384751..8b04c6c 100644 --- a/example-content/POBBLES - We Wish You.md +++ b/example-content/POBBLES - We Wish You.md @@ -1,4 +1,4 @@ +++ -catagories = ["Videos"] +categories = ["Videos"] youtube_id = "i5YDcT6db7g" +++ diff --git a/example-content/Riley.md b/example-content/Riley.md index 07ec645..a601dba 100644 --- a/example-content/Riley.md +++ b/example-content/Riley.md @@ -1,3 +1,3 @@ +++ -catagories = ["Contributors"] +categories = ["Contributors"] +++ diff --git a/pkg/content/discover.go b/pkg/content/discover.go index 60c44de..d571994 100644 --- a/pkg/content/discover.go +++ b/pkg/content/discover.go @@ -51,3 +51,23 @@ func AllPageTitles(pages map[string]*Page) []string { return allPageTitles } + +func FindRootPage(pages map[string]*Page) (*Page, error) { + var rootPage *Page + + for _, page := range pages { + if page.Meta.Root { + if rootPage != nil { + return &Page{}, fmt.Errorf("multiple root pages found") + } + + rootPage = page + } + } + + if rootPage == nil { + return &Page{}, fmt.Errorf("no root page found") + } + + return rootPage, nil +} diff --git a/pkg/content/parsing.go b/pkg/content/parsing.go index 1e0e7d8..bdfd8ea 100644 --- a/pkg/content/parsing.go +++ b/pkg/content/parsing.go @@ -8,17 +8,27 @@ import ( "strings" "github.com/yuin/goldmark" + "github.com/yuin/goldmark/parser" "go.abhg.dev/goldmark/frontmatter" "go.abhg.dev/goldmark/wikilink" "github.com/fogo-sh/almanac/pkg/utils" ) +type PageMeta struct { + Categories []string `toml:"categories"` + Date string `toml:"date"` + Redirect string `toml:"redirect"` + Root bool `toml:"root"` + YoutubeId string `toml:"youtube_id"` +} + type Page struct { Title string Path string LinksTo []string Backlinks []string + Meta PageMeta ParsedContent []byte } @@ -42,8 +52,7 @@ func ParsePageFile(path string) (Page, error) { var linksTo = make([]string, 0) - var buf bytes.Buffer - if err := goldmark.New(goldmark.WithExtensions( + md := goldmark.New(goldmark.WithExtensions( &frontmatter.Extender{}, &wikilink.Extender{ Resolver: WikiLinkResolver{ @@ -53,16 +62,33 @@ func ParsePageFile(path string) (Page, error) { }, }, }, - )).Convert(content, &buf); err != nil { + )) + + ctx := parser.NewContext() + + var buf bytes.Buffer + err = md.Convert(content, &buf, parser.WithContext(ctx)) + if err != nil { return Page{}, fmt.Errorf("failed to parse markdown: %w", err) } + var pageMeta PageMeta + + data := frontmatter.Get(ctx) + + if data != nil { + if err := data.Decode(&pageMeta); err != nil { + return Page{}, fmt.Errorf("failed to decode frontmatter: %w", err) + } + } + pageTitle := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) return Page{ Title: pageTitle, LinksTo: linksTo, Path: path, + Meta: pageMeta, ParsedContent: buf.Bytes(), }, nil } diff --git a/pkg/devserver/server.go b/pkg/devserver/server.go index 38708b5..b0a7f80 100644 --- a/pkg/devserver/server.go +++ b/pkg/devserver/server.go @@ -48,8 +48,10 @@ func (r *Renderer) Render(w io.Writer, name string, data interface{}, c echo.Con func serveNotFound(c echo.Context) error { return c.Render(http.StatusNotFound, "page", templates.PageTemplateData{ - Title: "Not found!", Content: template.HTML("

Looks like this page doesn't exist yet

"), + Page: &content.Page{ + Title: "Not Found", + }, }) } @@ -62,19 +64,29 @@ func (s *Server) servePage(c echo.Context) error { return fmt.Errorf("error discovering pages: %w", err) } - page, ok := pages[pageKey] + var page *content.Page - if !ok { - return serveNotFound(c) + if pageKey == "" { + page, err = content.FindRootPage(pages) + + if err != nil { + return serveNotFound(c) + } + } else { + var ok bool + page, ok = pages[pageKey] + + if !ok { + return serveNotFound(c) + } } allPageTitles := content.AllPageTitles(pages) return c.Render(http.StatusOK, "page", templates.PageTemplateData{ AllPageTitles: allPageTitles, - Title: page.Title, Content: template.HTML(string(page.ParsedContent)), - Backlinks: page.Backlinks, + Page: page, }) } @@ -108,6 +120,7 @@ func NewServer(config Config) *Server { } echoInst.GET("/:page", server.servePage) + echoInst.GET("/", server.servePage) echoInst.GET("*", serveNotFound) diff --git a/pkg/templates/output.go b/pkg/templates/output.go index 43ea5a8..88e61b4 100644 --- a/pkg/templates/output.go +++ b/pkg/templates/output.go @@ -35,9 +35,8 @@ func OutputAllPagesToDisk(pages map[string]*content.Page, outputDir string) erro err = PageTemplate.Execute(w, PageTemplateData{ AllPageTitles: allPageTitles, - Title: page.Title, + Page: page, Content: template.HTML(string(page.ParsedContent)), - Backlinks: page.Backlinks, }) if err != nil { return fmt.Errorf("failed to execute template: %w", err) diff --git a/pkg/templates/page.go b/pkg/templates/page.go index 90741f3..61ec62f 100644 --- a/pkg/templates/page.go +++ b/pkg/templates/page.go @@ -1,18 +1,21 @@ package templates -import "html/template" +import ( + "html/template" + + "github.com/fogo-sh/almanac/pkg/content" +) type PageTemplateData struct { AllPageTitles []string - Title string + Page *content.Page Content template.HTML - Backlinks []string } var pageTemplateContent = ` - {{ .Title }} + {{ .Page.Title }} @@ -25,17 +28,29 @@ var pageTemplateContent = `
-

{{ .Title }}

+

{{ .Page.Title }}

+ + {{ if .Page.Meta.YoutubeId }} + + {{ end }} + {{ .Content }} - {{ if .Backlinks }} -
-

Backlinks

- -
+ + {{ if .Page.Backlinks }} +
+

Backlinks

+ +
{{ end }}