Skip to content

Commit 66d9f93

Browse files
authored
Merge pull request #506 from compscidr/fix/archives-sort-order
Sort archives newest first
2 parents 9fba59c + 65b8af2 commit 66d9f93

4 files changed

Lines changed: 79 additions & 31 deletions

File tree

blog/blog.go

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (b *Blog) getTags() []Tag {
9292
return tags
9393
}
9494

95-
func (b *Blog) getArchivesByYear() map[string][]Post {
95+
func (b *Blog) getArchivesByYear() ([]string, map[string][]Post) {
9696
archive := make(map[string][]Post)
9797
posts := b.GetPosts(false)
9898
for _, post := range posts {
@@ -102,22 +102,32 @@ func (b *Blog) getArchivesByYear() map[string][]Post {
102102
}
103103
archive[year] = append(archive[year], post)
104104
}
105-
return archive
105+
keys := make([]string, 0, len(archive))
106+
for k := range archive {
107+
keys = append(keys, k)
108+
}
109+
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
110+
return keys, archive
106111
}
107112

108-
func (b *Blog) getArchivesByYearMonth() map[string][]Post {
113+
func (b *Blog) getArchivesByYearMonth() ([]string, map[string][]Post) {
109114
archive := make(map[string][]Post)
110115
posts := b.GetPosts(false)
111116
for _, post := range posts {
112117
year := strconv.Itoa(post.CreatedAt.Year())
113-
month := strconv.Itoa(int(post.CreatedAt.Month()))
118+
month := fmt.Sprintf("%02d", int(post.CreatedAt.Month()))
114119
yearMonth := year + "/" + month
115120
if _, ok := archive[yearMonth]; !ok {
116121
archive[yearMonth] = make([]Post, 0)
117122
}
118123
archive[yearMonth] = append(archive[yearMonth], post)
119124
}
120-
return archive
125+
keys := make([]string, 0, len(archive))
126+
for k := range archive {
127+
keys = append(keys, k)
128+
}
129+
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
130+
return keys, archive
121131
}
122132

123133
func (b *Blog) GetPostObject(c *gin.Context) (*Post, error) {
@@ -477,11 +487,15 @@ func (b *Blog) DynamicPage(c *gin.Context, page *Page) {
477487
"nav_pages": navPages,
478488
})
479489
case PageTypeArchives:
490+
yearKeys, byYear := b.getArchivesByYear()
491+
monthKeys, byYearMonth := b.getArchivesByYearMonth()
480492
c.HTML(http.StatusOK, "page_archives.html", gin.H{
481-
"logged_in": b.auth.IsLoggedIn(c),
482-
"is_admin": b.auth.IsAdmin(c),
483-
"byYear": b.getArchivesByYear(),
484-
"byYearMonth": b.getArchivesByYearMonth(),
493+
"logged_in": b.auth.IsLoggedIn(c),
494+
"is_admin": b.auth.IsAdmin(c),
495+
"yearKeys": yearKeys,
496+
"byYear": byYear,
497+
"yearMonthKeys": monthKeys,
498+
"byYearMonth": byYearMonth,
485499
"page": page,
486500
"version": b.Version,
487501
"title": page.Title,
@@ -902,17 +916,21 @@ func (b *Blog) About(c *gin.Context) {
902916

903917
// Archives shows the posts by year, month, etc.
904918
func (b *Blog) Archives(c *gin.Context) {
919+
yearKeys, byYear := b.getArchivesByYear()
920+
monthKeys, byYearMonth := b.getArchivesByYearMonth()
905921
c.HTML(http.StatusOK, "archives.html", gin.H{
906-
"logged_in": b.auth.IsLoggedIn(c),
907-
"is_admin": b.auth.IsAdmin(c),
908-
"version": b.Version,
909-
"title": "Blog Archives",
910-
"byYear": b.getArchivesByYear(),
911-
"byYearMonth": b.getArchivesByYearMonth(),
912-
"recent": b.GetLatest(),
913-
"admin_page": false,
914-
"settings": b.GetSettings(),
915-
"nav_pages": b.GetNavPages(),
922+
"logged_in": b.auth.IsLoggedIn(c),
923+
"is_admin": b.auth.IsAdmin(c),
924+
"version": b.Version,
925+
"title": "Blog Archives",
926+
"yearKeys": yearKeys,
927+
"byYear": byYear,
928+
"yearMonthKeys": monthKeys,
929+
"byYearMonth": byYearMonth,
930+
"recent": b.GetLatest(),
931+
"admin_page": false,
932+
"settings": b.GetSettings(),
933+
"nav_pages": b.GetNavPages(),
916934
})
917935
}
918936

blog/blog_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"strconv"
1616
"strings"
1717
"testing"
18+
"time"
1819

1920
"github.com/gin-contrib/sessions"
2021
"github.com/gin-contrib/sessions/cookie"
@@ -216,6 +217,14 @@ func TestBlogWorkflow(t *testing.T) {
216217
t.Fatalf("Expected to get status %d for /tags but instead got %d\n", http.StatusOK, w.Code)
217218
}
218219

220+
// Create posts in different years/months so we can verify archive sort order
221+
oldPost := blog.Post{Title: "Old Post", Content: "old", Slug: "old-post", PostTypeID: defaultType.ID}
222+
oldPost.CreatedAt = time.Date(2023, 3, 15, 0, 0, 0, 0, time.UTC)
223+
db.Create(&oldPost)
224+
newPost := blog.Post{Title: "New Post", Content: "new", Slug: "new-post", PostTypeID: defaultType.ID}
225+
newPost.CreatedAt = time.Date(2025, 11, 1, 0, 0, 0, 0, time.UTC)
226+
db.Create(&newPost)
227+
219228
// Dynamic page: /archives resolves via NoRoute
220229
a.On("IsAdmin", mock.Anything).Return(false).Once()
221230
a.On("IsLoggedIn", mock.Anything).Return(false).Once()
@@ -225,6 +234,23 @@ func TestBlogWorkflow(t *testing.T) {
225234
if w.Code != http.StatusOK {
226235
t.Fatalf("Expected to get status %d for /archives but instead got %d\n", http.StatusOK, w.Code)
227236
}
237+
// Verify archives are sorted newest first
238+
body := w.Body.String()
239+
idx2025 := strings.Index(body, "2025")
240+
idx2023 := strings.Index(body, "2023")
241+
if idx2025 < 0 || idx2023 < 0 {
242+
t.Fatal("Expected archives page to contain both 2025 and 2023")
243+
}
244+
if idx2025 > idx2023 {
245+
t.Fatal("Expected 2025 to appear before 2023 in archives (newest first)")
246+
}
247+
// Verify months are zero-padded
248+
if !strings.Contains(body, "2023/03") {
249+
t.Fatal("Expected zero-padded month 2023/03 in archives")
250+
}
251+
if !strings.Contains(body, "2025/11") {
252+
t.Fatal("Expected 2025/11 in archives")
253+
}
228254

229255
//get home
230256
a.On("IsAdmin", mock.Anything).Return(false).Once()

templates/archives.html

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@
44
<h1 class="text-left">Archives</h1>
55

66
<h2>By Year</h2>
7-
{{ range $year, $posts := .byYear }}
8-
<h3>{{ $year }} </h3>
7+
{{ $byYear := .byYear }}
8+
{{ range .yearKeys }}
9+
<h3>{{ . }} </h3>
910
<ul>
10-
{{ range $posts }}
11+
{{ range index $byYear . }}
1112
<li><a href="{{ .Permalink }}" title="{{ .Title }}">{{ .Title }}</a></li>
1213
{{ end }}
1314
</ul>
1415
{{ end }}
1516
<h2>By Month</h2>
16-
{{ range $yearMonth, $posts := .byYearMonth }}
17-
<h3>{{ $yearMonth }} </h3>
17+
{{ $byYearMonth := .byYearMonth }}
18+
{{ range .yearMonthKeys }}
19+
<h3>{{ . }} </h3>
1820
<ul>
19-
{{ range $posts }}
21+
{{ range index $byYearMonth . }}
2022
<li><a href="{{ .Permalink }}" title="{{ .Title }}">{{ .Title }}</a></li>
2123
{{ end }}
2224
</ul>

templates/page_archives.html

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@ <h1 class="text-left">{{ .page.Title }}</h1>
2323
{{ end }}
2424

2525
<h2>By Year</h2>
26-
{{ range $year, $posts := .byYear }}
27-
<h3>{{ $year }} </h3>
26+
{{ $byYear := .byYear }}
27+
{{ range .yearKeys }}
28+
<h3>{{ . }} </h3>
2829
<ul>
29-
{{ range $posts }}
30+
{{ range index $byYear . }}
3031
<li><a href="{{ .Permalink }}" title="{{ .Title }}">{{ .Title }}</a></li>
3132
{{ end }}
3233
</ul>
3334
{{ end }}
3435
<h2>By Month</h2>
35-
{{ range $yearMonth, $posts := .byYearMonth }}
36-
<h3>{{ $yearMonth }} </h3>
36+
{{ $byYearMonth := .byYearMonth }}
37+
{{ range .yearMonthKeys }}
38+
<h3>{{ . }} </h3>
3739
<ul>
38-
{{ range $posts }}
40+
{{ range index $byYearMonth . }}
3941
<li><a href="{{ .Permalink }}" title="{{ .Title }}">{{ .Title }}</a></li>
4042
{{ end }}
4143
</ul>

0 commit comments

Comments
 (0)