diff options
author | Brian Picciano <mediocregopher@gmail.com> | 2022-05-20 17:43:47 -0600 |
---|---|---|
committer | Brian Picciano <mediocregopher@gmail.com> | 2022-05-20 17:43:47 -0600 |
commit | 1f42c5e000c3fc09e201a8e87eb79ea05cad7e35 (patch) | |
tree | 1c23c94cf1a59e25aea63e4f422aa7cd86387805 | |
parent | 47d478790742a8876af187b34b766b0e8a772bf5 (diff) |
Add tag selector to index
-rw-r--r-- | srv/src/http/index.go | 24 | ||||
-rw-r--r-- | srv/src/http/tpl/index.html | 7 | ||||
-rw-r--r-- | srv/src/post/post.go | 27 | ||||
-rw-r--r-- | srv/src/post/post_test.go | 4 |
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) }) } |