From 839343a3108734a15e331b542a20ed9c77ef582b Mon Sep 17 00:00:00 2001 From: grm Date: Wed, 16 Sep 2026 00:00:57 +0300 Subject: Add a search box module and a search page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Readers had no way to find a post. The new "search" module goes in the header (a bar under the nav) or a side column (a box with a heading) and is a plain GET form to /search, so it works without JavaScript. The results page lists the published posts of every page whose title or Markdown body matches the query — case-insensitive, each word literal, spaces meaning "anything in between", in order — as title, date and a short snippet with the match marked, 20 per page. modules.kind is a CHECK constraint, so a migration widens it; "search" becomes a reserved page slug so the literal route keeps winning over /{page}. moduleHasSettings now takes the module: a header search box has no heading, hence nothing to edit. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A --- internal/web/layout.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'internal/web/layout.go') diff --git a/internal/web/layout.go b/internal/web/layout.go index b8069a0..0d51068 100644 --- a/internal/web/layout.go +++ b/internal/web/layout.go @@ -12,9 +12,9 @@ import ( // Modules a blogger can put in each area. Header modules are the big // blocks; the side columns take the small boxes; the footer its own set. var moduleKinds = map[string][]string{ - "header": {"title", "logo", "menu"}, - "left": {"menu", "recent", "archive", "tags", "tagcloud", "logo", "html"}, - "right": {"menu", "recent", "archive", "tags", "tagcloud", "logo", "html"}, + "header": {"title", "logo", "menu", "search"}, + "left": {"menu", "search", "recent", "archive", "tags", "tagcloud", "logo", "html"}, + "right": {"menu", "search", "recent", "archive", "tags", "tagcloud", "logo", "html"}, "above": {"html"}, "below": {"html"}, "footer": {"text", "rss", "sitemap", "html"}, @@ -29,6 +29,7 @@ var moduleNames = map[string]string{ "recent": "Recent posts", "tags": "Tags", "tagcloud": "Tag cloud", + "search": "Search box", "html": "Custom HTML", "rss": "RSS link", "text": "Footer text", @@ -52,11 +53,14 @@ func allowedKind(area, kind string) bool { return false } -// moduleHasSettings says whether the module has an edit page. -func moduleHasSettings(kind string) bool { - switch kind { +// moduleHasSettings says whether the module has an edit page. Header modules +// show no heading, so a search box there has nothing to edit. +func moduleHasSettings(m store.Module) bool { + switch m.Kind { case "html", "text", "recent", "archive", "sitemap", "tags", "tagcloud": return true + case "search": + return m.Area != "header" } return false } -- cgit v1.2.3