diff --git a/renderer.go b/renderer.go index f3cf193..707c32b 100644 --- a/renderer.go +++ b/renderer.go @@ -75,8 +75,7 @@ func RenderIndexPage(user User) (string, error) { posts, _ := user.Posts() postHtml := "" - for _, postId := range posts { - post, _ := user.GetPost(postId) + for _, post := range posts { postHtml += "

" + post.Title() + "

\n" } diff --git a/rss.go b/rss.go index ba0a03a..b1839de 100644 --- a/rss.go +++ b/rss.go @@ -40,8 +40,7 @@ func RenderRSSFeed(user User) (string, error) { } posts, _ := user.Posts() - for _, postId := range posts { - post, _ := user.GetPost(postId) + for _, post := range posts { _, meta := post.MarkdownData() rss.Channel.Items = append(rss.Channel.Items, RSSItem{ Guid: post.FullUrl(), diff --git a/user.go b/user.go index a3652c6..0875e5f 100644 --- a/user.go +++ b/user.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "path" + "sort" "time" "gopkg.in/yaml.v2" @@ -51,17 +52,37 @@ func (user User) Name() string { return user.name } -func (user User) Posts() ([]string, error) { +func (user User) Posts() ([]Post, error) { postFiles := listDir(path.Join(user.Dir(), "public")) - posts := make([]string, 0) + posts := make([]Post, 0) for _, id := range postFiles { // if is a directory and has index.md, add to posts if dirExists(path.Join(user.Dir(), "public", id)) { if fileExists(path.Join(user.Dir(), "public", id, "index.md")) { - posts = append(posts, id) + post, _ := user.GetPost(id) + posts = append(posts, post) } } } + + // sort posts by date + sort.Slice(posts, func(i, j int) bool { + _, markdownData_i := posts[i].MarkdownData() + _, markdownData_j := posts[j].MarkdownData() + + date_i, err := time.Parse(time.RFC1123Z, markdownData_i.Date) + if err != nil { + // invalid date -> use 1970-01-01 + date_i = time.Time{} + } + date_j, err := time.Parse(time.RFC1123Z, markdownData_j.Date) + if err != nil { + // invalid date -> use 1970-01-01 + date_j = time.Time{} + } + return date_i.After(date_j) + }) + return posts, nil } @@ -156,8 +177,7 @@ func (user User) PostAliases() (map[string]*Post, error) { if err != nil { return post_aliases, err } - for _, id := range posts { - post, err := user.GetPost(id) + for _, post := range posts { if err != nil { return post_aliases, err } diff --git a/user_test.go b/user_test.go index 7cc21ec..9595937 100644 --- a/user_test.go +++ b/user_test.go @@ -40,7 +40,7 @@ func TestCreateNewPostAddsDateToMetaBlock(t *testing.T) { // Create a new post user.CreateNewPost("testpost") posts, _ := user.Posts() - post, _ := user.GetPost(posts[0]) + post, _ := user.GetPost(posts[0].Id()) _, meta := post.MarkdownData() if meta.Date == "" { t.Error("Found no date. Got: " + meta.Date) @@ -99,17 +99,21 @@ func TestCannotListUserPostsInSubdirectories(t *testing.T) { os.WriteFile(path.Join(user.PostDir(), "foo/index.md"), []byte(content), 0644) os.WriteFile(path.Join(user.PostDir(), "foo/bar/index.md"), []byte(content), 0644) posts, _ := user.Posts() - if !contains(posts, "foo") { + postIds := []string{} + for _, p := range posts { + postIds = append(postIds, p.Id()) + } + if !contains(postIds, "foo") { t.Error("Does not contain post: foo. Found:") for _, p := range posts { - t.Error("\t" + p) + t.Error("\t" + p.Id()) } } - if contains(posts, "foo/bar") { + if contains(postIds, "foo/bar") { t.Error("Invalid post found: foo/bar. Found:") for _, p := range posts { - t.Error("\t" + p) + t.Error("\t" + p.Id()) } } } @@ -131,10 +135,14 @@ func TestCannotListUserPostsWithoutIndexMd(t *testing.T) { os.WriteFile(path.Join(user.PostDir(), "foo/bar/index.md"), []byte(content), 0644) posts, _ := user.Posts() - if contains(posts, "foo") { + postIds := []string{} + for _, p := range posts { + postIds = append(postIds, p.Id()) + } + if contains(postIds, "foo") { t.Error("Contains invalid post: foo. Found:") for _, p := range posts { - t.Error("\t" + p) + t.Error("\t" + p.Id()) } } } @@ -145,7 +153,7 @@ func TestCanLoadPost(t *testing.T) { user.CreateNewPost("testpost") posts, _ := user.Posts() - post, _ := user.GetPost(posts[0]) + post, _ := user.GetPost(posts[0].Id()) if post.Title() != "testpost" { t.Error("Wrong title, Got: " + post.Title()) } @@ -164,3 +172,61 @@ func TestUserFullUrl(t *testing.T) { t.Error("Wrong url path, Expected: " + "http://localhost:8080/user/" + user.Name() + "/" + " Got: " + user.FullUrl()) } } + +func TestPostsSortedByPublishingDateLatestFirst(t *testing.T) { + user := getTestUser() + // Create a new post + post1, _ := user.CreateNewPost("testpost") + post2, _ := user.CreateNewPost("testpost2") + + content := "---\n" + content += "title: Test Post\n" + content += "date: Wed, 17 Aug 2022 10:50:02 +0000\n" + content += "---\n" + content += "This is a test" + os.WriteFile(post1.ContentFile(), []byte(content), 0644) + + content = "---\n" + content += "title: Test Post 2\n" + content += "date: Wed, 17 Aug 2022 20:50:06 +0000\n" + content += "---\n" + content += "This is a test" + os.WriteFile(post2.ContentFile(), []byte(content), 0644) + + posts, _ := user.Posts() + if posts[0].Id() != post2.Id() { + t.Error("Wrong Id, Got: " + posts[0].Id()) + } + if posts[1].Id() != post1.Id() { + t.Error("Wrong Id, Got: " + posts[1].Id()) + } +} + +func TestPostsSortedByPublishingDateBrokenAtBottom(t *testing.T) { + user := getTestUser() + // Create a new post + post1, _ := user.CreateNewPost("testpost") + post2, _ := user.CreateNewPost("testpost2") + + content := "---\n" + content += "title: Test Post\n" + content += "date: Wed, 17 +0000\n" + content += "---\n" + content += "This is a test" + os.WriteFile(post1.ContentFile(), []byte(content), 0644) + + content = "---\n" + content += "title: Test Post 2\n" + content += "date: Wed, 17 Aug 2022 20:50:06 +0000\n" + content += "---\n" + content += "This is a test" + os.WriteFile(post2.ContentFile(), []byte(content), 0644) + + posts, _ := user.Posts() + if posts[0].Id() != post2.Id() { + t.Error("Wrong Id, Got: " + posts[0].Id()) + } + if posts[1].Id() != post1.Id() { + t.Error("Wrong Id, Got: " + posts[1].Id()) + } +}