From c7585b3e0de98e5e73d9675d0ad84d72d07a2fff Mon Sep 17 00:00:00 2001 From: Jack Arthur Harrhy Date: Sun, 27 Aug 2023 16:46:04 -0230 Subject: [PATCH] page listing, discover all pages instead of just 1 --- pkg/content/discover.go | 41 +++++++++++++++++++++++++++ pkg/content/parsing.go | 20 ++++++++----- pkg/devserver/server.go | 27 +++++++++--------- pkg/static/static/assets/css/main.css | 13 +++++++++ pkg/templates/page.go | 18 +++++++++--- 5 files changed, 94 insertions(+), 25 deletions(-) create mode 100644 pkg/content/discover.go diff --git a/pkg/content/discover.go b/pkg/content/discover.go new file mode 100644 index 0000000..3a8da01 --- /dev/null +++ b/pkg/content/discover.go @@ -0,0 +1,41 @@ +package content + +import ( + "fmt" + "path/filepath" + "sort" +) + +func DiscoverPages(path string) (map[string]Page, error) { + paths, error := filepath.Glob(filepath.Join(path, "*.md")) + + if error != nil { + return nil, fmt.Errorf("failed to glob files: %w", error) + } + + pages := make(map[string]Page) + + for _, path := range paths { + page, error := ParsePageFile(path) + if error != nil { + return nil, fmt.Errorf("failed to parse page: %w", error) + } + + pages[page.Title] = page + } + + return pages, nil +} + +func AllPageTitles(pages map[string]Page) []string { + allPageTitles := make([]string, 0, len(pages)) + for key := range pages { + allPageTitles = append(allPageTitles, key) + } + + sort.Slice(allPageTitles, func(i, j int) bool { + return allPageTitles[i] < allPageTitles[j] + }) + + return allPageTitles +} diff --git a/pkg/content/parsing.go b/pkg/content/parsing.go index 3dd30a6..eeb413a 100644 --- a/pkg/content/parsing.go +++ b/pkg/content/parsing.go @@ -4,6 +4,8 @@ import ( "bytes" "fmt" "os" + "path/filepath" + "strings" "github.com/yuin/goldmark" "go.abhg.dev/goldmark/frontmatter" @@ -12,27 +14,28 @@ import ( "github.com/fogo-sh/almanac/pkg/utils" ) -type File struct { +type Page struct { + Title string Path string ParsedContent []byte } -func ParseFile(path string) (File, error) { +func ParsePageFile(path string) (Page, error) { f, err := os.Open(path) if err != nil { - return File{}, fmt.Errorf("failed to open file: %w", err) + return Page{}, fmt.Errorf("failed to open file: %w", err) } defer utils.DeferredClose(f) stat, err := f.Stat() if err != nil { - return File{}, fmt.Errorf("failed to stat file: %w", err) + return Page{}, fmt.Errorf("failed to stat file: %w", err) } content := make([]byte, stat.Size()) _, err = f.Read(content) if err != nil { - return File{}, fmt.Errorf("failed to read file: %w", err) + return Page{}, fmt.Errorf("failed to read file: %w", err) } var buf bytes.Buffer @@ -42,10 +45,13 @@ func ParseFile(path string) (File, error) { Resolver: WikiLinkResolver{}, }, )).Convert(content, &buf); err != nil { - return File{}, fmt.Errorf("failed to parse markdown: %w", err) + return Page{}, fmt.Errorf("failed to parse markdown: %w", err) } - return File{ + pageTitle := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) + + return Page{ + Title: pageTitle, Path: path, ParsedContent: buf.Bytes(), }, nil diff --git a/pkg/devserver/server.go b/pkg/devserver/server.go index ff53dc9..1b4dc00 100644 --- a/pkg/devserver/server.go +++ b/pkg/devserver/server.go @@ -7,8 +7,6 @@ import ( "io" "log/slog" "net/http" - "os" - "path" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" @@ -56,25 +54,26 @@ func serveNotFound(c echo.Context) error { } func (s *Server) servePage(c echo.Context) error { - page := c.Param("page") - contentPath := path.Join(s.config.ContentDir, page+".md") + pageKey := c.Param("page") + + pages, err := content.DiscoverPages(s.config.ContentDir) - _, err := os.Stat(contentPath) if err != nil { - if errors.Is(err, os.ErrNotExist) { - return serveNotFound(c) - } - return fmt.Errorf("error checking file: %w", err) + return fmt.Errorf("error discovering pages: %w", err) } - file, err := content.ParseFile(contentPath) - if err != nil { - return fmt.Errorf("error processing file: %w", err) + page, ok := pages[pageKey] + + if !ok { + return serveNotFound(c) } + allPageTitles := content.AllPageTitles(pages) + return c.Render(http.StatusOK, "page", templates.PageTemplateData{ - Title: page, - Content: template.HTML(string(file.ParsedContent)), + AllPageTitles: allPageTitles, + Title: page.Title, + Content: template.HTML(string(page.ParsedContent)), }) } diff --git a/pkg/static/static/assets/css/main.css b/pkg/static/static/assets/css/main.css index 4b3a624..6edf151 100644 --- a/pkg/static/static/assets/css/main.css +++ b/pkg/static/static/assets/css/main.css @@ -8,6 +8,10 @@ } body { + max-width: 80rem; + margin: 0 auto; + display: flex; + gap: 1rem; background-color: var(--bg); padding: 1rem; } @@ -15,3 +19,12 @@ body { body > :first-child { margin-top: 0; } + +nav { + padding-top: 4rem; + width: 20rem; +} + +main { + width: 100%; +} diff --git a/pkg/templates/page.go b/pkg/templates/page.go index d637a8a..b1bb928 100644 --- a/pkg/templates/page.go +++ b/pkg/templates/page.go @@ -3,8 +3,9 @@ package templates import "html/template" type PageTemplateData struct { - Title string - Content template.HTML + AllPageTitles []string + Title string + Content template.HTML } var pageTemplateContent = ` @@ -14,8 +15,17 @@ var pageTemplateContent = ` -

{{ .Title }}

- {{ .Content }} + +
+

{{ .Title }}

+ {{ .Content }} +
`