diff options
Diffstat (limited to 'internal/web')
| -rw-r--r-- | internal/web/handlers_layout.go | 4 | ||||
| -rw-r--r-- | internal/web/layout.go | 16 | ||||
| -rw-r--r-- | internal/web/static/blog.css | 15 | ||||
| -rw-r--r-- | internal/web/templates/blog/search.html | 2 | ||||
| -rw-r--r-- | internal/web/templates/layouts/blog.html | 12 |
5 files changed, 34 insertions, 15 deletions
diff --git a/internal/web/handlers_layout.go b/internal/web/handlers_layout.go index d89cd18..db4f47c 100644 --- a/internal/web/handlers_layout.go +++ b/internal/web/handlers_layout.go @@ -126,10 +126,6 @@ func (s *Server) handleModuleAdd(w http.ResponseWriter, r *http.Request) { m.Count = 10 case "tagcloud": m.Title = i18n.T(blogLang, "Tag cloud") - case "search": - if area != "header" { - m.Title = i18n.T(blogLang, "Search") - } } m, err := blogStore(r).CreateModule(r.Context(), m) if err != nil { diff --git a/internal/web/layout.go b/internal/web/layout.go index 0d51068..6f5c84f 100644 --- a/internal/web/layout.go +++ b/internal/web/layout.go @@ -124,6 +124,9 @@ type Layout struct { // A column is laid out when it has something to show — or always, when // the theme keeps the columns' space. HasLeft, HasRight bool + // A header search box sits in the menu row when there is one, so the two + // header modules need to know about each other. + HeaderMenu, HeaderSearch bool } // buildLayout groups modules by area, dropping areas the theme has switched off. @@ -136,6 +139,8 @@ func buildLayout(t Theme, mods []store.Module) Layout { switch m.Area { case "header": l.Header = append(l.Header, m) + l.HeaderMenu = l.HeaderMenu || m.Kind == "menu" + l.HeaderSearch = l.HeaderSearch || m.Kind == "search" case "left": l.Left = append(l.Left, m) case "right": @@ -181,6 +186,17 @@ func (l Layout) NeedsTags() bool { return false } +// HasSearch says whether a visible module offers a search box (the search +// page shows its own only when none does). +func (l Layout) HasSearch() bool { + for _, m := range l.all() { + if m.Kind == "search" { + return true + } + } + return false +} + // MaxRecent is the longest "recent posts" list any visible module wants (0 = none). func (l Layout) MaxRecent() int { n := 0 diff --git a/internal/web/static/blog.css b/internal/web/static/blog.css index e2bf588..4fd7b76 100644 --- a/internal/web/static/blog.css +++ b/internal/web/static/blog.css @@ -80,12 +80,15 @@ img { max-width: 100%; height: auto; } .tc-3 { font-size: 1.2em; } .tc-4 { font-size: 1.45em; } .tc-5 { font-size: 1.75em; } -.site-search { border-bottom: 1px solid rgba(0,0,0,0.1); } -.search-inner { padding: 0.5em 1em; } +/* search box: in the header it floats at the right end of the menu row (its + own thin bar only when there is no menu); in a column it fills the box */ .search-form { margin: 0; } -.search-form input { padding: 0.35em 0.5em; font: inherit; max-width: 100%; } -.search-form button { padding: 0.35em 0.8em; font: inherit; } -.mod-search input { width: 100%; margin-bottom: 0.4em; } +.search-form input { padding: 0.3em 0.5em; font: inherit; font-size: 0.9em; max-width: 100%; border: 1px solid rgba(0,0,0,0.25); border-radius: 3px; background: rgba(255,255,255,0.85); color: #222; } +.site-nav .search-form { float: right; margin: 0.35em 0 0.35em 1em; } +.site-nav .nav-inner { overflow: hidden; } +.site-search { border-bottom: 1px solid rgba(0,0,0,0.1); } +.search-inner { padding: 0.4em 1em; } +.mod-search input { width: 100%; } .search-page { margin-bottom: 1.5em; } .search-results { list-style: none; margin: 0; padding: 0; } .search-results li { margin: 0 0 1.2em; } @@ -104,4 +107,6 @@ img { max-width: 100%; height: auto; } .col-left, .col-right { padding: 0; margin-top: 1.5em; } .col-left { order: 0; } .col-empty { display: none; } /* a reserved-but-empty column has nothing to stack */ + .site-nav .search-form { float: none; margin: 0.35em 0.8em; } + .site-nav .search-form input { width: 100%; } } diff --git a/internal/web/templates/blog/search.html b/internal/web/templates/blog/search.html index b146f5e..7ee05fc 100644 --- a/internal/web/templates/blog/search.html +++ b/internal/web/templates/blog/search.html @@ -1,7 +1,7 @@ {{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.layout.HasSearch}}<div class="search-page">{{template "searchform" .}}</div>{{end}} {{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}} diff --git a/internal/web/templates/layouts/blog.html b/internal/web/templates/layouts/blog.html index 3e854f6..6e8b819 100644 --- a/internal/web/templates/layouts/blog.html +++ b/internal/web/templates/layouts/blog.html @@ -58,7 +58,7 @@ </div> {{- else if eq $m.Kind "logo"}}{{if $t.Logo}}{{if eq $m.Area "header"}}<div class="wrap header-logo"><a href="/"><img class="logo" src="/media/{{$t.Logo}}" alt="{{$r.Blog.Title}}"></a></div> {{else}}<div class="mod mod-logo"><a href="/"><img class="logo" src="/media/{{$t.Logo}}" alt="{{$r.Blog.Title}}"></a></div>{{end}}{{end}} -{{- else if eq $m.Kind "menu"}}{{if eq $m.Area "header"}}<div class="site-nav"><div class="wrap nav-inner">{{template "menulinks" $r}}</div></div> +{{- else if eq $m.Kind "menu"}}{{if eq $m.Area "header"}}<div class="site-nav"><div class="wrap nav-inner">{{if $r.Data.layout.HeaderSearch}}{{template "searchform" $r}}{{end}}{{template "menulinks" $r}}</div></div> {{else}}<div class="mod site-nav mod-menu">{{template "modtitle" $m}}<div class="nav-inner">{{template "menulinks" $r}}</div></div>{{end}} {{- else if eq $m.Kind "recent"}}<div class="mod mod-recent">{{template "modtitle" $m}} <ul>{{range $i, $p := $r.Data.recent}}{{if lt $i $m.Count}}<li><a href="/{{$p.PageSlug}}/{{$p.Slug}}">{{$p.Title}}</a></li>{{end}}{{end}}</ul> @@ -76,7 +76,7 @@ {{- else if eq $m.Kind "tagcloud"}}<div class="mod mod-tagcloud">{{template "modtitle" $m}} <p class="tagcloud">{{range $r.Data.tagcloud}}<a class="tc-{{.Size}}" href="/tag/{{.Slug}}" title="{{.Count}}">{{.Name}}</a> {{else}}<span class="muted">{{t "No tags yet."}}</span>{{end}}</p> </div> -{{- else if eq $m.Kind "search"}}{{if eq $m.Area "header"}}<div class="site-search"><div class="wrap search-inner">{{template "searchform" $r}}</div></div> +{{- else if eq $m.Kind "search"}}{{if eq $m.Area "header"}}{{if not $r.Data.layout.HeaderMenu}}<div class="site-search"><div class="wrap search-inner">{{template "searchform" $r}}</div></div>{{end}} {{else}}<div class="mod mod-search">{{template "modtitle" $m}}{{template "searchform" $r}}</div>{{end}} {{- else if eq $m.Kind "html"}}{{if not $m.Body}}{{else if or (eq $m.Area "above") (eq $m.Area "below")}}<div class="custom-html custom-html-{{$m.Area}}">{{html $m.Body}}</div> {{else}}<div class="mod mod-html">{{template "modtitle" $m}}{{html $m.Body}}</div>{{end}} @@ -87,9 +87,11 @@ </div> {{- end}}{{end}} -{{/* The search box: a plain GET form, so it works without JavaScript. .Data.q - only exists on the search page, hence the with. */}} -{{define "searchform"}}<form method="get" action="/search" class="search-form"><input type="search" name="q"{{with .Data.q}} value="{{.}}"{{end}} placeholder="{{t "Search…"}}" size="18"> <button type="submit">{{t "Search"}}</button></form>{{end}} +{{/* The search box: a plain GET form, so it works without JavaScript. Just the + input — Enter (or the phone keyboard's search key) submits a one-field + form everywhere, and the placeholder is the label, so the page does not + say "Search" over and over. .Data.q only exists on the search page. */}} +{{define "searchform"}}<form method="get" action="/search" class="search-form"><input type="search" name="q"{{with .Data.q}} value="{{.}}"{{end}} placeholder="{{t "Search…"}}" aria-label="{{t "Search…"}}" size="16"></form>{{end}} {{define "modtitle"}}{{if .Title}}<h3 class="mod-title">{{.Title}}</h3>{{end}}{{end}} |
