diff options
Diffstat (limited to 'internal/server/frontpage.go')
| -rw-r--r-- | internal/server/frontpage.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/internal/server/frontpage.go b/internal/server/frontpage.go new file mode 100644 index 0000000..47a766a --- /dev/null +++ b/internal/server/frontpage.go @@ -0,0 +1,86 @@ +package server + +import ( + "html/template" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "nebbet.no/internal/db" +) + +type FrontpageHandler struct { + DB *db.MetaDB + SearchDB *db.SearchDB + Templates *template.Template +} + +type frontpageData struct { + Posts []db.PostRecord + Query string + ActiveTag string +} + +func NewFrontpageHandler(metaDB *db.MetaDB, searchDB *db.SearchDB, tmpl *template.Template) *FrontpageHandler { + return &FrontpageHandler{DB: metaDB, SearchDB: searchDB, Templates: tmpl} +} + +func (h *FrontpageHandler) Serve(c *gin.Context) { + query := strings.TrimSpace(c.Query("q")) + tag := strings.TrimSpace(c.Query("tag")) + + data := frontpageData{ + Query: query, + ActiveTag: tag, + } + + if query != "" { + // Full-text search + results, err := h.SearchDB.Search(query) + if err == nil { + data.Posts = searchResultsToPosts(results, h.DB) + } + } else { + posts, err := h.DB.ListPosts(false) // exclude drafts + if err == nil { + if tag != "" { + posts = filterByTag(posts, tag) + } + data.Posts = posts + } + } + + c.Header("Content-Type", "text/html; charset=utf-8") + if err := h.Templates.ExecuteTemplate(c.Writer, "index.html", data); err != nil { + c.AbortWithStatus(http.StatusInternalServerError) + } +} + +func filterByTag(posts []db.PostRecord, tag string) []db.PostRecord { + var filtered []db.PostRecord + for _, p := range posts { + for _, t := range p.Tags { + if strings.EqualFold(t, tag) { + filtered = append(filtered, p) + break + } + } + } + return filtered +} + +func searchResultsToPosts(results []db.SearchResult, metaDB *db.MetaDB) []db.PostRecord { + var posts []db.PostRecord + for _, r := range results { + slug := strings.TrimPrefix(r.Path, "/") + if slug == r.Path { + continue // not a post + } + post, err := metaDB.GetPost(slug) + if err != nil || post.Draft { + continue + } + posts = append(posts, *post) + } + return posts +} |
