From 7662ae52c08c659f5aaf69f446822f48c3d0a831 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 16 Apr 2026 22:56:16 +0300 Subject: refactor(generator): load themes & shared HTML from embedded template files (task s4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the 12 theme HTML templates out of theme_*.go (~185KB of raw-string literals) and the shared navDefs/faviconHeadHTML fragments out of shared.go/favicon.go into separate .tmpl files under internal/generator/templates/{themes,shared}/. A new templates subpackage owns a //go:embed FS and exposes Theme(), Shared() and ThemeNames() helpers so the binary still ships fully self-contained. The hand-maintained themeRegistry map is replaced by on-startup enumeration of the embedded FS; getTheme/ListThemes now derive theme names from the template files themselves, and navDefs/faviconHeadHTML are loaded once at package init. Rendered output is byte-equivalent — all unit tests and integration tests pass, go vet is clean. Made-with: Cursor --- internal/generator/favicon.go | 19 +- internal/generator/generator_test.go | 6 +- internal/generator/shared.go | 422 +-------------------- internal/generator/templates.go | 10 +- internal/generator/templates/embed.go | 62 +++ .../generator/templates/shared/favicon_head.tmpl | 2 + internal/generator/templates/shared/nav.tmpl | 400 +++++++++++++++++++ internal/generator/templates/themes/aurora.tmpl | 298 +++++++++++++++ internal/generator/templates/themes/brutalist.tmpl | 204 ++++++++++ internal/generator/templates/themes/cosmos.tmpl | 314 +++++++++++++++ internal/generator/templates/themes/dos.tmpl | 236 ++++++++++++ internal/generator/templates/themes/matrix.tmpl | 257 +++++++++++++ internal/generator/templates/themes/neon.tmpl | 280 ++++++++++++++ internal/generator/templates/themes/ocean.tmpl | 324 ++++++++++++++++ internal/generator/templates/themes/plasma.tmpl | 236 ++++++++++++ internal/generator/templates/themes/retro.tmpl | 238 ++++++++++++ internal/generator/templates/themes/synthwave.tmpl | 258 +++++++++++++ internal/generator/templates/themes/terminal.tmpl | 220 +++++++++++ internal/generator/templates/themes/volcano.tmpl | 336 ++++++++++++++++ internal/generator/theme_aurora.go | 303 --------------- internal/generator/theme_brutalist.go | 209 ---------- internal/generator/theme_dos.go | 242 ------------ internal/generator/theme_glass.go | 319 ---------------- internal/generator/theme_matrix.go | 264 ------------- internal/generator/theme_minimal.go | 241 ------------ internal/generator/theme_neon.go | 285 -------------- internal/generator/theme_ocean.go | 329 ---------------- internal/generator/theme_paper.go | 341 ----------------- internal/generator/theme_retro.go | 245 ------------ internal/generator/theme_synthwave.go | 263 ------------- internal/generator/theme_terminal.go | 226 ----------- internal/generator/themes.go | 83 ++-- 32 files changed, 3759 insertions(+), 3713 deletions(-) create mode 100644 internal/generator/templates/embed.go create mode 100644 internal/generator/templates/shared/favicon_head.tmpl create mode 100644 internal/generator/templates/shared/nav.tmpl create mode 100644 internal/generator/templates/themes/aurora.tmpl create mode 100644 internal/generator/templates/themes/brutalist.tmpl create mode 100644 internal/generator/templates/themes/cosmos.tmpl create mode 100644 internal/generator/templates/themes/dos.tmpl create mode 100644 internal/generator/templates/themes/matrix.tmpl create mode 100644 internal/generator/templates/themes/neon.tmpl create mode 100644 internal/generator/templates/themes/ocean.tmpl create mode 100644 internal/generator/templates/themes/plasma.tmpl create mode 100644 internal/generator/templates/themes/retro.tmpl create mode 100644 internal/generator/templates/themes/synthwave.tmpl create mode 100644 internal/generator/templates/themes/terminal.tmpl create mode 100644 internal/generator/templates/themes/volcano.tmpl delete mode 100644 internal/generator/theme_aurora.go delete mode 100644 internal/generator/theme_brutalist.go delete mode 100644 internal/generator/theme_dos.go delete mode 100644 internal/generator/theme_glass.go delete mode 100644 internal/generator/theme_matrix.go delete mode 100644 internal/generator/theme_minimal.go delete mode 100644 internal/generator/theme_neon.go delete mode 100644 internal/generator/theme_ocean.go delete mode 100644 internal/generator/theme_paper.go delete mode 100644 internal/generator/theme_retro.go delete mode 100644 internal/generator/theme_synthwave.go delete mode 100644 internal/generator/theme_terminal.go diff --git a/internal/generator/favicon.go b/internal/generator/favicon.go index 0d2d094..a4a8251 100644 --- a/internal/generator/favicon.go +++ b/internal/generator/favicon.go @@ -6,14 +6,27 @@ import ( "fmt" "image" "image/color" + "log" "os" "path/filepath" "strings" + + "codeberg.org/snonux/snonux/internal/generator/templates" ) -const faviconHeadHTML = ` - -` +// faviconHeadHTML is the fragment injected into every theme's +// . Loaded at startup from the embedded templates FS so no HTML lives in +// the Go sources. +var faviconHeadHTML = loadFaviconHeadHTML() + +func loadFaviconHeadHTML() string { + s, err := templates.Shared("favicon_head") + if err != nil { + log.Printf("warning: could not load favicon_head template: %v", err) + return "" + } + return s +} func injectSharedHead(theme string) string { if strings.Contains(theme, `rel="icon"`) { diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index e3b09bf..7b0009c 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -92,7 +92,7 @@ func TestJSONStringOrNull(t *testing.T) { func TestThemeSoundPresetsMatchRegistry(t *testing.T) { t.Parallel() - for name := range themeRegistry { + for name := range themeSet { if _, ok := themeSoundPresets[name]; !ok { t.Errorf("theme %q has no sound preset in themeSoundPresets", name) } @@ -221,8 +221,8 @@ func TestInjectSharedHead_addsFaviconLink(t *testing.T) { func TestListThemes_sortedAndComplete(t *testing.T) { t.Parallel() names := ListThemes() - if len(names) != len(themeRegistry) { - t.Fatalf("len=%d, want %d", len(names), len(themeRegistry)) + if len(names) != len(themeSet) { + t.Fatalf("len=%d, want %d", len(names), len(themeSet)) } for i := 1; i < len(names); i++ { if names[i] <= names[i-1] { diff --git a/internal/generator/shared.go b/internal/generator/shared.go index 11dbeed..d0badb8 100644 --- a/internal/generator/shared.go +++ b/internal/generator/shared.go @@ -1,416 +1,30 @@ package generator -// navDefs is appended to every theme template when parsing. +import ( + "log" + + "codeberg.org/snonux/snonux/internal/generator/templates" +) + +// navDefs is the content of templates/shared/nav.tmpl loaded once at startup. // It defines named sub-templates shared across all themes: // - "splashGate" — synchronous script: first child of ; sets html.sno-splash-skip when // splash should not run (?splash=0, not index path, or Referer from same-site index/pageN). // - "navhints" — keyboard shortcut hint bar HTML -// - "navSharedCSSInner" — shared CSS (injected inside each theme’s + + + {{template "splashGate"}} + + + +
+
+ + +
+ {{template "navhints" .}} +
+ {{range $i, $post := .Posts}} +
+
+
@snonux
+
{{$post.FormattedTime}}
+
+
{{$post.ContentHTML}}
+
+ {{end}} +
+ {{if or .PrevPage .NextPage}} + + {{end}} +
+ {{template "navmodal" .}} +