aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/templates
diff options
context:
space:
mode:
Diffstat (limited to 'internal/web/templates')
-rw-r--r--internal/web/templates/dashboard/design.html11
-rw-r--r--internal/web/templates/layouts/blog.html46
2 files changed, 48 insertions, 9 deletions
diff --git a/internal/web/templates/dashboard/design.html b/internal/web/templates/dashboard/design.html
index ec4f70d..0b27e17 100644
--- a/internal/web/templates/dashboard/design.html
+++ b/internal/web/templates/dashboard/design.html
@@ -187,6 +187,17 @@
<label for="nav-hover-custom" class="check">{{t "Change colour when the mouse is over a link"}}</label>
<label class="hover-color">{{t "Hover colour"}}<br><input type="color" name="nav_hover" value="{{if $t.NavHover}}{{$t.NavHover}}{{else}}{{$t.NavText}}{{end}}"></label>
</div>
+ <h3>{{t "When the menu does not fit"}}</h3>
+ <div class="hoverpick">
+ <input type="checkbox" name="nav_fold" id="nav-fold"{{if $t.NavFold}} checked{{end}}>
+ <label for="nav-fold" class="check">{{t "Fold the header menu into a button when its links do not fit on one line"}}</label>
+ <label class="hover-color">{{t "Button"}}<br><select name="nav_fold_label">
+ <option value="icon"{{if eq $t.NavFoldLabel "icon"}} selected{{end}}>&#9776;</option>
+ <option value="text"{{if eq $t.NavFoldLabel "text"}} selected{{end}}>{{t "Menu"}}</option>
+ <option value="both"{{if eq $t.NavFoldLabel "both"}} selected{{end}}>&#9776; {{t "Menu"}}</option>
+ </select></label>
+ </div>
+ <p class="muted small">{{t "The button sits at the right of the title or logo just above the menu, or in the menu bar itself when nothing is above it, and opens the links as a list. Readers whose browser runs no scripts get it on phones."}}</p>
</div>
<div class="card" id="content">
diff --git a/internal/web/templates/layouts/blog.html b/internal/web/templates/layouts/blog.html
index 7ee0b54..d55512a 100644
--- a/internal/web/templates/layouts/blog.html
+++ b/internal/web/templates/layouts/blog.html
@@ -13,10 +13,7 @@
</head>
{{$l := .Data.layout}}
<body class="{{if $l.HasLeft}}has-left {{end}}{{if $l.HasRight}}has-right {{end}}{{.Data.theme.NavClass}}{{with .Data.theme.TitleRuleClass}} {{.}}{{end}}">
-{{if or $l.Header .Data.theme.HeaderImage}}{{if .Data.theme.HeaderOn}}<div class="site-header">
- {{if .Data.theme.HeaderImage}}<div class="header-image"><a href="/"><img src="/media/{{.Data.theme.HeaderImage}}" alt=""></a></div>{{end}}
- {{range $l.Header}}{{template "module" (dict "m" . "root" $)}}{{end}}
-</div>{{end}}{{end}}
+{{if or $l.Header .Data.theme.HeaderImage}}{{if .Data.theme.HeaderOn}}{{template "siteheader" .}}{{end}}{{end}}
<div class="wrap body-wrap cols">
{{$n := .Data.notices}}
<div class="col col-main"><div class="content">
@@ -43,6 +40,37 @@
</body>
</html>{{end}}
+{{/* The header: the banner, then its modules in order. With the menu folding
+ (Layout.Fold) a hidden checkbox comes first: it is the open/closed state,
+ so the burger label toggles the menu with no script and in old browsers
+ (`:checked ~` reaches every block after it). Folding itself is decided by
+ the script below — any link on a second line means the menu does not fit —
+ which drops nav-auto, the no-script fallback blog.css folds on phones. */}}
+{{define "siteheader"}}{{$l := .Data.layout}}{{$t := .Data.theme}}<div class="site-header{{if $l.Fold}} nav-fold nav-auto{{end}}{{if eq $t.HeaderAlign "center"}} header-center{{end}}">
+ {{if $l.Fold}}<input type="checkbox" id="nav-toggle" class="nav-toggle" aria-label="{{t "Menu"}}">{{end}}
+ {{if $t.HeaderImage}}<div class="header-image"><a href="/"><img src="/media/{{$t.HeaderImage}}" alt=""></a></div>{{end}}
+ {{range $i, $m := $l.Header}}{{template "module" (dict "m" $m "root" $ "burger" (and $l.Fold (eq $i $l.BurgerAt)))}}{{end}}
+</div>{{if $l.Fold}}<script>(function () {
+ var h = document.querySelector && document.querySelector(".site-header.nav-fold"), cb = document.getElementById("nav-toggle");
+ if (!h || !h.classList || !window.addEventListener) return; // old browsers keep the phone-only fallback
+ var nav = h.querySelector(".site-nav .nav-inner"), links = nav && nav.getElementsByTagName("a"), timer;
+ if (!links || !links.length) return;
+ h.classList.remove("nav-auto");
+ function fit() { // unfold, look, refold before anything is painted
+ h.classList.remove("nav-folded");
+ var top = links[0].offsetTop, wrapped = false;
+ for (var i = 1; i < links.length && !wrapped; i++) wrapped = links[i].offsetTop !== top;
+ if (wrapped) h.classList.add("nav-folded");
+ }
+ fit();
+ window.addEventListener("load", fit); // web fonts change the widths
+ window.addEventListener("resize", function () { clearTimeout(timer); timer = setTimeout(fit, 100); });
+ if (cb) cb.addEventListener("change", function () { cb.setAttribute("aria-expanded", cb.checked ? "true" : "false"); });
+})();</script>{{end}}{{end}}
+
+{{/* The fold button, a label for the checkbox above. */}}
+{{define "burger"}}<label for="nav-toggle" class="nav-burger burger-{{.NavFoldLabel}}"><span class="nb-icon" aria-hidden="true">&#9776;</span><span class="nb-text">{{t "Menu"}}</span></label>{{end}}
+
{{define "notices"}}{{if .}}<div class="notices">
{{range .}}<aside class="notice notice-{{.Style}}{{if .Title}} headed{{end}}{{if .Width}} w-{{.Width}}{{end}}">
{{if .Title}}<h3 class="notice-title">{{.Title}}</h3>{{end}}
@@ -53,14 +81,14 @@
{{/* One layout module. .m is the store.Module, .root the page data; the same
kind renders differently in the header (big blocks) and elsewhere (boxes). */}}
-{{define "module"}}{{$m := .m}}{{$r := .root}}{{$t := $r.Data.theme}}{{$rc := $t.RuleClass}}
-{{- if eq $m.Kind "title"}}<div class="wrap header-text{{with $rc}} {{.}}{{end}}">{{template "rule" (dict "before" true "rc" $rc "theme" $t)}}<div class="brand">
+{{define "module"}}{{$m := .m}}{{$r := .root}}{{$t := $r.Data.theme}}{{$rc := $t.RuleClass}}{{$b := .burger}}
+{{- if eq $m.Kind "title"}}<div class="wrap header-text{{with $rc}} {{.}}{{end}}{{if $b}} has-burger{{end}}">{{template "rule" (dict "before" true "rc" $rc "theme" $t)}}<div class="brand">
<h1 class="site-title"><a href="/">{{$r.Blog.Title}}</a></h1>
{{if $r.Blog.Tagline}}<p class="tagline">{{$r.Blog.Tagline}}</p>{{end}}
-</div>{{template "rule" (dict "before" false "rc" $rc "theme" $t)}}</div>
-{{- else if eq $m.Kind "logo"}}{{if $t.Logo}}{{if eq $m.Area "header"}}<div class="wrap header-logo{{with $rc}} {{.}}{{end}}">{{template "rule" (dict "before" true "rc" $rc "theme" $t)}}<div class="brand"><a href="/"><img class="logo" src="/media/{{$t.Logo}}" alt="{{$r.Blog.Title}}"></a></div>{{template "rule" (dict "before" false "rc" $rc "theme" $t)}}</div>
+</div>{{template "rule" (dict "before" false "rc" $rc "theme" $t)}}{{if $b}}{{template "burger" $t}}{{end}}</div>
+{{- else if eq $m.Kind "logo"}}{{if $t.Logo}}{{if eq $m.Area "header"}}<div class="wrap header-logo{{with $rc}} {{.}}{{end}}{{if $b}} has-burger{{end}}">{{template "rule" (dict "before" true "rc" $rc "theme" $t)}}<div class="brand"><a href="/"><img class="logo" src="/media/{{$t.Logo}}" alt="{{$r.Blog.Title}}"></a></div>{{template "rule" (dict "before" false "rc" $rc "theme" $t)}}{{if $b}}{{template "burger" $t}}{{end}}</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">{{if $r.Data.layout.HeaderSearch}}{{template "searchform" $r}}{{end}}{{template "menulinks" $r}}</div></div>
+{{- else if eq $m.Kind "menu"}}{{if eq $m.Area "header"}}<div class="site-nav{{if $b}} has-burger{{end}}"><div class="wrap nav-inner">{{if $b}}{{template "burger" $t}}{{end}}{{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>