Blog archive page

pull/4/head
Noah 2017-11-24 13:27:08 -08:00
parent 34d444ab96
commit ab5430df26
3 changed files with 84 additions and 4 deletions

View File

@ -8,6 +8,7 @@ import (
"sort"
"strconv"
"strings"
"time"
"github.com/gorilla/mux"
"github.com/kirsle/blog/core/models/posts"
@ -24,10 +25,18 @@ type PostMeta struct {
Snipped bool
}
// Archive holds data for a piece of the blog archive.
type Archive struct {
Label string
Date time.Time
Posts []posts.Post
}
// BlogRoutes attaches the blog routes to the app.
func (b *Blog) BlogRoutes(r *mux.Router) {
// Public routes
r.HandleFunc("/blog", b.BlogIndex)
r.HandleFunc("/archive", b.BlogArchive)
r.HandleFunc("/tagged/{tag}", b.Tagged)
// Login-required routers.
@ -203,6 +212,53 @@ func (b *Blog) PartialIndex(w http.ResponseWriter, r *http.Request,
b.RenderTemplate(w, r, "blog/index", v)
}
// BlogArchive summarizes all blog entries in an archive view.
func (b *Blog) BlogArchive(w http.ResponseWriter, r *http.Request) {
idx, err := posts.GetIndex()
if err != nil {
b.BadRequest(w, r, "Error getting blog index")
return
}
// Group posts by calendar month.
var months []string
byMonth := map[string]*Archive{}
for _, post := range idx.Posts {
// Exclude certain posts
if (post.Privacy == PRIVATE || post.Privacy == UNLISTED) && !b.LoggedIn(r) {
continue
} else if post.Privacy == DRAFT {
continue
}
label := post.Created.Format("2006-02")
if _, ok := byMonth[label]; !ok {
months = append(months, label)
byMonth[label] = &Archive{
Label: label,
Date: time.Date(post.Created.Year(), post.Created.Month(), post.Created.Day(), 0, 0, 0, 0, time.UTC),
Posts: []posts.Post{},
}
}
byMonth[label].Posts = append(byMonth[label].Posts, post)
}
// Sort the months.
sort.Sort(sort.Reverse(sort.StringSlice(months)))
// Prepare the response.
result := []*Archive{}
for _, label := range months {
sort.Sort(sort.Reverse(posts.ByUpdated(byMonth[label].Posts)))
result = append(result, byMonth[label])
}
v := NewVars(map[interface{}]interface{}{
"Archive": result,
})
b.RenderTemplate(w, r, "blog/archive", v)
}
// viewPost is the underlying implementation of the handler to view a blog
// post, so that it can be called from non-http.HandlerFunc contexts.
func (b *Blog) viewPost(w http.ResponseWriter, r *http.Request, fragment string) error {

24
root/blog/archive.gohtml Normal file
View File

@ -0,0 +1,24 @@
{{ define "title" }}Archive{{ end }}
{{ define "content" }}
<h1>Archive</h1>
{{ range .Data.Archive }}
<h3>{{ .Date.Format "January, 2006" }}</h3>
<ul class="list-unstyled">
{{ range .Posts }}
<li class="list-item">
<a href="/{{ .Fragment }}">{{ .Title }}</a>
<small class="blog-meta">
{{ .Created.Format "Jan 02 2006" }}
{{ if ne .Privacy "public" }}
<span class="blog-{{ .Privacy }}">[{{ .Privacy }}]</span>
{{ end }}
</small>
</li>
{{ end }}
</ul>
{{ end }}
{{ end }}

View File

@ -5,10 +5,10 @@
<div class="col text-right">
<ul class="list-inline">
{{ if .Data.PreviousPage }}
<li class="list-inline-item"><a href="/?page={{ .Data.PreviousPage }}">Earlier</a></li>
<li class="list-inline-item"><a href="?page={{ .Data.PreviousPage }}">Earlier</a></li>
{{ end }}
{{ if .Data.NextPage }}
<li class="list-inline-item"><a href="/?page={{ .Data.NextPage }}">Older</a></li>
<li class="list-inline-item"><a href="?page={{ .Data.NextPage }}">Older</a></li>
{{ end }}
</div>
</div>
@ -35,10 +35,10 @@
<div class="col text-right">
<ul class="list-inline">
{{ if .Data.PreviousPage }}
<li class="list-inline-item"><a href="/?page={{ .Data.PreviousPage }}">Earlier</a></li>
<li class="list-inline-item"><a href="?page={{ .Data.PreviousPage }}">Earlier</a></li>
{{ end }}
{{ if .Data.NextPage }}
<li class="list-inline-item"><a href="/?page={{ .Data.NextPage }}">Older</a></li>
<li class="list-inline-item"><a href="?page={{ .Data.NextPage }}">Older</a></li>
{{ end }}
</div>
</div>