Tags List page
parent
117542b23c
commit
fd1494cf75
|
@ -26,6 +26,11 @@ func init() {
|
||||||
Methods: []string{"GET"},
|
Methods: []string{"GET"},
|
||||||
Handler: BlogIndex(models.Public, false),
|
Handler: BlogIndex(models.Public, false),
|
||||||
})
|
})
|
||||||
|
glue.Register(glue.Endpoint{
|
||||||
|
Path: "/tagged",
|
||||||
|
Methods: []string{"GET"},
|
||||||
|
Handler: TagIndex,
|
||||||
|
})
|
||||||
glue.Register(glue.Endpoint{
|
glue.Register(glue.Endpoint{
|
||||||
Path: "/tagged/{tag}",
|
Path: "/tagged/{tag}",
|
||||||
Methods: []string{"GET"},
|
Methods: []string{"GET"},
|
||||||
|
@ -158,6 +163,18 @@ func PartialBlogIndex(r *http.Request, tag, privacy string) template.HTML {
|
||||||
return template.HTML(html.String())
|
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"
|
// EditPost at "/blog/edit"
|
||||||
func EditPost(w http.ResponseWriter, r *http.Request) {
|
func EditPost(w http.ResponseWriter, r *http.Request) {
|
||||||
v := responses.NewTemplateVars(w, r)
|
v := responses.NewTemplateVars(w, r)
|
||||||
|
|
|
@ -48,13 +48,6 @@ type PagedPosts struct {
|
||||||
PreviousPage int
|
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.
|
// New creates a new Post model.
|
||||||
func (m postMan) New() Post {
|
func (m postMan) New() Post {
|
||||||
return Post{
|
return Post{
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -32,6 +32,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="/about" class="nav-link">About</a>
|
<a href="/about" class="nav-link">About</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/tagged" class="nav-link">Tags</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="/archive" class="nav-link">Archive</a>
|
<a href="/archive" class="nav-link">Archive</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -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 }}
|
Loading…
Reference in New Issue