summaryrefslogtreecommitdiff
path: root/srv
diff options
context:
space:
mode:
Diffstat (limited to 'srv')
-rw-r--r--srv/src/http/index.go24
-rw-r--r--srv/src/http/tpl/index.html7
-rw-r--r--srv/src/post/post.go27
-rw-r--r--srv/src/post/post_test.go4
4 files changed, 61 insertions, 1 deletions
diff --git a/srv/src/http/index.go b/srv/src/http/index.go
index 4557f95..aa606d6 100644
--- a/srv/src/http/index.go
+++ b/srv/src/http/index.go
@@ -30,7 +30,19 @@ func (a *api) renderIndexHandler() http.Handler {
return
}
- posts, hasMore, err := a.params.PostStore.Get(page, pageCount)
+ tag := r.FormValue("tag")
+
+ var (
+ posts []post.StoredPost
+ hasMore bool
+ )
+
+ if tag == "" {
+ posts, hasMore, err = a.params.PostStore.Get(page, pageCount)
+ } else {
+ posts, err = a.params.PostStore.GetByTag(tag)
+ }
+
if err != nil {
apiutil.InternalServerError(
rw, r, fmt.Errorf("fetching page %d of posts: %w", page, err),
@@ -38,13 +50,23 @@ func (a *api) renderIndexHandler() http.Handler {
return
}
+ tags, err := a.params.PostStore.GetTags()
+ if err != nil {
+ apiutil.InternalServerError(
+ rw, r, fmt.Errorf("fething tags: %w", err),
+ )
+ return
+ }
+
tplPayload := struct {
Posts []post.StoredPost
PrevPage, NextPage int
+ Tags []string
}{
Posts: posts,
PrevPage: -1,
NextPage: -1,
+ Tags: tags,
}
if page > 0 {
diff --git a/srv/src/http/tpl/index.html b/srv/src/http/tpl/index.html
index e27cbef..c75affc 100644
--- a/srv/src/http/tpl/index.html
+++ b/srv/src/http/tpl/index.html
@@ -1,5 +1,12 @@
{{ define "body" }}
+ <p>
+ By Tag:
+ {{ range .Payload.Tags }}
+ <a href="{{ BlogURL "/" }}?tag={{ . }}">{{ . }}</a>
+ {{ end }}
+ </p>
+
<ul id="posts-list">
{{ range .Payload.Posts }}
diff --git a/srv/src/post/post.go b/srv/src/post/post.go
index bf851af..29a984f 100644
--- a/srv/src/post/post.go
+++ b/srv/src/post/post.go
@@ -68,6 +68,9 @@ type Store interface {
// descending, or empty slice.
GetByTag(tag string) ([]StoredPost, error)
+ // GetTags returns all tags which have at least one Post using them.
+ GetTags() ([]string, error)
+
// Delete will delete the StoredPost with the given ID.
Delete(id string) error
}
@@ -340,6 +343,30 @@ func (s *store) GetByTag(tag string) ([]StoredPost, error) {
return posts, err
}
+func (s *store) GetTags() ([]string, error) {
+
+ rows, err := s.db.Query(`SELECT tag FROM post_tags GROUP BY tag`)
+ if err != nil {
+ return nil, fmt.Errorf("querying all tags: %w", err)
+ }
+ defer rows.Close()
+
+ var tags []string
+
+ for rows.Next() {
+
+ var tag string
+
+ if err := rows.Scan(&tag); err != nil {
+ return nil, fmt.Errorf("scanning tag: %w", err)
+ }
+
+ tags = append(tags, tag)
+ }
+
+ return tags, nil
+}
+
func (s *store) Delete(id string) error {
tx, err := s.db.Begin()
diff --git a/srv/src/post/post_test.go b/srv/src/post/post_test.go
index 97757e5..b6d8a2e 100644
--- a/srv/src/post/post_test.go
+++ b/srv/src/post/post_test.go
@@ -252,5 +252,9 @@ func TestStore(t *testing.T) {
bazPosts, err := h.store.GetByTag("baz")
assert.NoError(t, err)
assert.Empty(t, bazPosts)
+
+ tags, err := h.store.GetTags()
+ assert.NoError(t, err)
+ assert.ElementsMatch(t, []string{"foo", "bar"}, tags)
})
}