diff options
| author | grm <grm@eyesin.space> | 2026-09-16 00:00:57 +0300 |
|---|---|---|
| committer | grm <grm@eyesin.space> | 2026-09-16 00:00:57 +0300 |
| commit | 839343a3108734a15e331b542a20ed9c77ef582b (patch) | |
| tree | a6aabc8719c16398bf1ccd874a7efe865b364a9e /internal/web/templates/blog/search.html | |
| parent | 628dcb814ece6335667e2b719049728aa161d8c9 (diff) | |
| download | blogspace-839343a3108734a15e331b542a20ed9c77ef582b.tar.gz blogspace-839343a3108734a15e331b542a20ed9c77ef582b.tar.bz2 blogspace-839343a3108734a15e331b542a20ed9c77ef582b.zip | |
Add a search box module and a search page
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/templates/blog/search.html')
| -rw-r--r-- | internal/web/templates/blog/search.html | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/internal/web/templates/blog/search.html b/internal/web/templates/blog/search.html new file mode 100644 index 0000000..b146f5e --- /dev/null +++ b/internal/web/templates/blog/search.html @@ -0,0 +1,23 @@ +{{define "title"}}{{if .Data.q}}{{tf "Results for “%s”" .Data.q}}{{else}}{{t "Search"}}{{end}} · {{.Blog.Title}}{{end}} +{{define "content"}} +<h1 class="page-title">{{if .Data.q}}{{tf "Results for “%s”" .Data.q}}{{else}}{{t "Search"}}{{end}}</h1> +<div class="search-page">{{template "searchform" .}}</div> +{{if not .Data.q}}<p class="muted">{{t "Type a word or two to find posts."}}</p> +{{else if not .Data.hits}}<p class="muted">{{tf "Nothing matched “%s”." .Data.q}}</p> +{{else}} +<p class="muted small">{{if eq .Data.total 1}}{{t "One post matches."}}{{else}}{{tf "%d posts match." .Data.total}}{{end}}</p> +<ul class="search-results"> +{{range .Data.hits}}<li> + <a href="/{{.PageSlug}}/{{.Slug}}">{{.Title}}</a>{{if $.Data.theme.ShowDates}} <span class="post-date">{{postdate $.Data.theme.DateFormat .CreatedAt}}</span>{{end}} + <p class="snippet">{{.Snippet}}</p> +</li> +{{end}}</ul> +{{if gt .Data.lastPage 1}} +<div class="pager"> + {{if gt .Data.pageNum 1}}<a href="/search?q={{.Data.q}}&p={{sub .Data.pageNum 1}}">← {{t "Newer"}}</a>{{end}} + <span>{{tf "Page %d of %d" .Data.pageNum .Data.lastPage}}</span> + {{if lt .Data.pageNum .Data.lastPage}}<a href="/search?q={{.Data.q}}&p={{add .Data.pageNum 1}}">{{t "Older"}} →</a>{{end}} +</div> +{{end}} +{{end}} +{{end}} |
