Tags List page

master
Noah 2019-11-26 17:30:31 -08:00
parent 117542b23c
commit fd1494cf75
5 changed files with 90 additions and 7 deletions

View File

@ -26,6 +26,11 @@ func init() {
Methods: []string{"GET"},
Handler: BlogIndex(models.Public, false),
})
glue.Register(glue.Endpoint{
Path: "/tagged",
Methods: []string{"GET"},
Handler: TagIndex,
})
glue.Register(glue.Endpoint{
Path: "/tagged/{tag}",
Methods: []string{"GET"},
@ -158,6 +163,18 @@ func PartialBlogIndex(r *http.Request, tag, privacy string) template.HTML {
return template.HTML(html.String())
}
// TagIndex for "/tagged" to return all tags sorted by popularity.
func TagIndex(w http.ResponseWriter, r *http.Request) {
// If not logged in, only summarize public post tags.
var public = !authentication.LoggedIn(r)
tags := models.SummarizeTags(public)
v := responses.NewTemplateVars(w, r)
v.V["tags"] = tags
responses.RenderTemplate(w, r, "_builtin/blog/tags.gohtml", v)
}
// EditPost at "/blog/edit"
func EditPost(w http.ResponseWriter, r *http.Request) {
v := responses.NewTemplateVars(w, r)

View File

@ -48,13 +48,6 @@ type PagedPosts struct {
PreviousPage int
}
// TaggedPost associates tags to their posts.
type TaggedPost struct {
ID uint `gorm:"primary_key"`
Tag string
PostID uint // foreign key to Post
}
// New creates a new Post model.
func (m postMan) New() Post {
return Post{

57
pkg/models/tags.go Normal file
View File

@ -0,0 +1,57 @@
package models
import (
"git.kirsle.net/apps/gophertype/pkg/console"
)
// TaggedPost associates tags to their posts.
type TaggedPost struct {
ID uint `gorm:"primary_key"`
Tag string
PostID uint // foreign key to Post
}
// SummarizeTags returns the list of all tags ordered by frequency used.
// public: true for public view, don't count tags on private posts.
func SummarizeTags(public bool) []TagSummary {
var result []TagSummary
query := DB.Table("tagged_posts").
Select("tagged_posts.tag, count(tagged_posts.post_id) AS count").
Joins("JOIN posts ON posts.id = tagged_posts.post_id").
Group("tagged_posts.tag").
Order("count desc")
if public {
query = query.Where("posts.privacy = ?", Public)
}
rows, err := query.Rows()
if err != nil {
console.Error("SummarizeTags: query.Rows: %s", err)
}
for rows.Next() {
var (
tagName string
count int
)
if err := rows.Scan(&tagName, &count); err != nil {
console.Error("SummarizeTags: rows.Scan: %s", err)
}
result = append(result, TagSummary{
Tag: tagName,
Count: count,
})
}
return result
}
// TagSummary holds the result for SummarizeTags
type TagSummary struct {
Tag string
Count int
}

View File

@ -32,6 +32,9 @@
<li class="nav-item">
<a href="/about" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="/tagged" class="nav-link">Tags</a>
</li>
<li class="nav-item">
<a href="/archive" class="nav-link">Archive</a>
</li>

View File

@ -0,0 +1,13 @@
{{ define "title" }}Tags{{ end }}
{{ define "content" }}
<h1>Tags</h1>
<p>Sorted by most frequently used:</p>
<ul>
{{ range $tag := .V.tags }}
<li><a href="/tagged/{{ $tag.Tag }}">{{ $tag.Tag }}</a> ({{ $tag.Count }})</li>
{{ end }}
</ul>
{{ end }}