Blog archive page
This commit is contained in:
parent
34d444ab96
commit
ab5430df26
56
core/blog.go
56
core/blog.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/kirsle/blog/core/models/posts"
|
"github.com/kirsle/blog/core/models/posts"
|
||||||
|
@ -24,10 +25,18 @@ type PostMeta struct {
|
||||||
Snipped bool
|
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.
|
// BlogRoutes attaches the blog routes to the app.
|
||||||
func (b *Blog) BlogRoutes(r *mux.Router) {
|
func (b *Blog) BlogRoutes(r *mux.Router) {
|
||||||
// Public routes
|
// Public routes
|
||||||
r.HandleFunc("/blog", b.BlogIndex)
|
r.HandleFunc("/blog", b.BlogIndex)
|
||||||
|
r.HandleFunc("/archive", b.BlogArchive)
|
||||||
r.HandleFunc("/tagged/{tag}", b.Tagged)
|
r.HandleFunc("/tagged/{tag}", b.Tagged)
|
||||||
|
|
||||||
// Login-required routers.
|
// Login-required routers.
|
||||||
|
@ -203,6 +212,53 @@ func (b *Blog) PartialIndex(w http.ResponseWriter, r *http.Request,
|
||||||
b.RenderTemplate(w, r, "blog/index", v)
|
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
|
// viewPost is the underlying implementation of the handler to view a blog
|
||||||
// post, so that it can be called from non-http.HandlerFunc contexts.
|
// 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 {
|
func (b *Blog) viewPost(w http.ResponseWriter, r *http.Request, fragment string) error {
|
||||||
|
|
24
root/blog/archive.gohtml
Normal file
24
root/blog/archive.gohtml
Normal 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 }}
|
|
@ -5,10 +5,10 @@
|
||||||
<div class="col text-right">
|
<div class="col text-right">
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
{{ if .Data.PreviousPage }}
|
{{ 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 }}
|
{{ end }}
|
||||||
{{ if .Data.NextPage }}
|
{{ 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 }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,10 +35,10 @@
|
||||||
<div class="col text-right">
|
<div class="col text-right">
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
{{ if .Data.PreviousPage }}
|
{{ 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 }}
|
{{ end }}
|
||||||
{{ if .Data.NextPage }}
|
{{ 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 }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user