mykiwi/mykiwi.blogpublic Fork 0
47c5f424525f98bea38b29cd0aaa77accb2a704b
Commits
Clone
git clone https://git.rickub.com/mykiwi/mykiwi.blog.git
git clone ssh://git@rickub.com/mykiwi/mykiwi.blog.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

baseof.html · 140 lines · 7.2 KBHTML Blame HistoryRaw
Port fzakaria.com design to Hugo and add a homepage profile 1bdbd06 Romain Gautier yesterday1<!doctype html>
2<html lang="{{ site.Language.Lang }}">
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <meta name="color-scheme" content="light dark">
7 <meta name="theme-color" content="#f5f2ec" media="(prefers-color-scheme: light)">
8 <meta name="theme-color" content="#15171a" media="(prefers-color-scheme: dark)">
Add French/Portuguese/Japanese support, block indexing until launch f8c7bc5 Romain Gautier 19h ago9 {{ if site.Params.noindex }}
10 <meta name="robots" content="noindex, nofollow">
11 {{ end }}
Port fzakaria.com design to Hugo and add a homepage profile 1bdbd06 Romain Gautier yesterday12
13 <title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ .Title }} &middot; {{ site.Title }}{{ end }}</title>
14 {{- /*
15 Priority: this page's own front matter > an explicit site-wide
16 params.description override > params.profile.bio, stripped of markdown
17 down to plain text. Set params.description only when the SEO snippet
18 should say something different from the colophon bio; otherwise bio is
19 the single source of truth for both.
20 */}}
21 {{- $desc := .Description }}
22 {{- if not $desc }}{{ $desc = site.Params.description }}{{ end }}
23 {{- if not $desc }}{{ with site.Params.profile.bio }}{{ $desc = . | markdownify | plainify }}{{ end }}{{ end }}
24 {{ with $desc -}}
25 <meta name="description" content="{{ . }}">
26 {{- end }}
27
28 <!-- Fonts are self-hosted, so there is no third-party DNS + TLS before first paint. -->
29 <link rel="preload" href="/fonts/Newsreader-latin.woff2" as="font" type="font/woff2" crossorigin>
30 <link rel="preload" href="/fonts/JetBrainsMono-Regular.woff2" as="font" type="font/woff2" crossorigin>
Add SRI fingerprinting, inline avatar blurhash, and a language switcher icon 51380a7 Romain Gautier 13h ago31 {{- /*
32 fingerprint appends a content hash to the filename (style.abc123.css)
33 and gives us a real Subresource Integrity hash for free - without it
34 this was the one asset with no cache-busting at all: same URL forever,
35 so a browser (or CDN) holding a stale cached copy from before a
36 deploy has no way to know a new one exists.
37 */}}
Port fzakaria.com design to Hugo and add a homepage profile 1bdbd06 Romain Gautier yesterday38 {{ with resources.Get "css/style.scss" }}
39 {{ $opts := dict "transpiler" "dartsass" "outputStyle" "compressed" }}
Add SRI fingerprinting, inline avatar blurhash, and a language switcher icon 51380a7 Romain Gautier 13h ago40 {{ with . | toCSS $opts | fingerprint }}
41 <link rel="stylesheet" type="text/css" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}">
Port fzakaria.com design to Hugo and add a homepage profile 1bdbd06 Romain Gautier yesterday42 {{ end }}
43 {{ end }}
44
Add French/Portuguese/Japanese support, block indexing until launch f8c7bc5 Romain Gautier 19h ago45 <link rel="alternate" type="application/rss+xml" title="{{ site.Title }}" href="{{ "index.xml" | absLangURL }}">
46 {{- /* One hreflang tag per translated version of this page, so search
47 engines serve readers the right language instead of always the one
48 that happens to rank. x-default points at the lowest-weight (English)
49 translation, since that's the site's default language. */}}
50 {{- $translations := sort .AllTranslations "Language.Weight" }}
51 {{- range $translations }}
52 <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
53 {{- end }}
54 {{- with index $translations 0 }}
55 <link rel="alternate" hreflang="x-default" href="{{ .Permalink }}">
56 {{- end }}
Smooth page transitions with htmx boost, morph, and preload ca8b900 Romain Gautier 21h ago57 {{- /*
58 Declarative, not htmx.config.preload = {...} in a script: a <meta> tag
59 is parsed with the rest of the document, before any script (deferred or
60 not) runs, so htmx's constructor sees it synchronously and correctly
61 every time - no dependency on inline-script/defer/DOMContentLoaded
62 ordering at all. boostEvent switches hx-preload's trigger from the
63 default mousedown/touchstart to mouseover, so the fetch for a boosted
64 link starts the instant the cursor touches it rather than waiting for a
65 press.
66 */}}
67 <meta name="htmx-config" content="preload.boostEvent:mouseover">
Add SRI fingerprinting, inline avatar blurhash, and a language switcher icon 51380a7 Romain Gautier 13h ago68 {{ with resources.Get "js/htmx.min.js" | fingerprint }}
69 <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" defer></script>
70 {{ end }}
Smooth page transitions with htmx boost, morph, and preload ca8b900 Romain Gautier 21h ago71 {{- /*
72 Official htmx extension, vendored from the same htmx.org package as
73 htmx.min.js above (node_modules/htmx.org/dist/ext/hx-preload.min.js -
74 re-copy it from there on a version bump). Prefetches a boosted link's
75 GET response, reused automatically if the click follows within 5s.
76 Needs no hx-ext or other opt-in - just being loaded activates it for
77 every boosted anchor.
78 */}}
Add SRI fingerprinting, inline avatar blurhash, and a language switcher icon 51380a7 Romain Gautier 13h ago79 {{ with resources.Get "js/hx-preload.min.js" | fingerprint }}
80 <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" defer></script>
81 {{ end }}
Smooth page transitions with htmx boost, morph, and preload ca8b900 Romain Gautier 21h ago82 {{- /*
83 htmx's own browser back/forward handling (#restoreHistory) is a
84 separate code path from a boosted click - it calls htmx.ajax() directly
85 with swap:"outerSync" hardcoded, a full body replace, not our
86 innerMorph below. Left alone, a link click morphed smoothly but
87 back/forward tore the masthead down and rebuilt it. Preempt it with the
88 same config used everywhere else (kept as one Hugo value, $swapSpec,
89 rather than duplicated literals, so the two can't drift apart), and
90 abort a still-in-flight restore before starting the next one - the same
91 guard htmx's own implementation has - so mashing back/forward can't let
92 a slow, stale response land after a faster, newer one.
93
94 `defer` only affects scripts with a `src` - htmx.min.js and
95 hx-preload.min.js above genuinely wait until after parsing, but this
96 inline script has no `src` and runs immediately in place during
97 parsing, defer or not. It must not touch `htmx` at its top level, only
98 from inside a listener that fires later - hence DOMContentLoaded, which
99 is guaranteed to fire only after every deferred script, htmx.min.js and
100 hx-preload.min.js included, has already run.
101 */}}
102 {{- $swapSpec := dict "swap" "innerMorph" "transition" true }}
103 <script>
104 document.addEventListener("DOMContentLoaded", () => {
105 let restoreAbort;
106 document.addEventListener("htmx:before:history:restore", (e) => {
107 e.preventDefault();
108 restoreAbort?.abort();
109 restoreAbort = new AbortController();
110 htmx.ajax("GET", e.detail.path, {
111 target: document.body,
112 swap: "{{ $swapSpec.swap }}",
113 transition: {{ $swapSpec.transition }},
114 request: {headers: {}, signal: restoreAbort.signal},
115 });
116 });
117 });
118 </script>
Port fzakaria.com design to Hugo and add a homepage profile 1bdbd06 Romain Gautier yesterday119 {{ block "head" . }}{{ end }}
120 </head>
Smooth page transitions with htmx boost, morph, and preload ca8b900 Romain Gautier 21h ago121 {{- /*
122 Boosts every same-origin link/form into an AJAX navigation, inherited from
123 body down (htmx 4 requires the ":inherited" suffix explicitly - it no
124 longer inherits hx-* attributes implicitly). Boosted elements default to
125 targeting the whole <body>; innerMorph diffs the new body onto the old
126 one node-by-node instead of replacing it wholesale, so unchanged nodes
127 (the masthead's "mykiwi.blog" link) are patched in place rather than
128 torn down and re-flashed, while changed ones - the per-page signal SVG
129 path, the swapped #main content - update normally. transition:true wraps
130 that diff in a native View Transition for a soft cross-fade.
131 */}}
132 <body hx-boost:inherited="swap:{{ $swapSpec.swap }} transition:{{ $swapSpec.transition }}">
Add French/Portuguese/Japanese support, block indexing until launch f8c7bc5 Romain Gautier 19h ago133 <a class="skip-link" href="#main">{{ i18n "skipToContent" }}</a>
Port fzakaria.com design to Hugo and add a homepage profile 1bdbd06 Romain Gautier yesterday134 <div class="wrap">
135 {{ partial "masthead.html" . }}
136 <main id="main">{{ block "main" . }}{{ end }}</main>
137 {{ partial "site-foot.html" . }}
138 </div>
139 </body>
140</html>