From a46309ac64261814d931f538fad373ea8a4f0e95 Mon Sep 17 00:00:00 2001 From: ivar Date: Fri, 3 Apr 2026 14:46:05 +0200 Subject: feat: embed admin templates into binary with //go:embed Move admin templates from templates/admin/*.html to internal/admin/templates/*.html and embed them using //go:embed directive. This removes the runtime dependency on having template files on disk, allowing the templates to be compiled into the binary. Changes: - Add embed import and //go:embed directive for templates - Change ParseGlob() to ParseFS() to load from embedded filesystem - Copy templates to internal/admin/templates/ for embedding Co-Authored-By: Claude Haiku 4.5 --- internal/admin/server.go | 10 ++++-- internal/admin/templates/base.html | 34 ++++++++++++++++++++ internal/admin/templates/error.html | 7 +++++ internal/admin/templates/form.html | 62 +++++++++++++++++++++++++++++++++++++ internal/admin/templates/list.html | 40 ++++++++++++++++++++++++ 5 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 internal/admin/templates/base.html create mode 100644 internal/admin/templates/error.html create mode 100644 internal/admin/templates/form.html create mode 100644 internal/admin/templates/list.html (limited to 'internal') diff --git a/internal/admin/server.go b/internal/admin/server.go index 33413ee..b36c598 100644 --- a/internal/admin/server.go +++ b/internal/admin/server.go @@ -4,6 +4,7 @@ package admin import ( + "embed" "fmt" "html/template" "net/http" @@ -19,6 +20,9 @@ import ( "nebbet.no/internal/builder" ) +//go:embed templates/*.html +var adminTemplates embed.FS + // Server is an http.Handler that serves the admin post-management UI. type Server struct { // PostsDir is the directory where post markdown files are stored, @@ -353,7 +357,7 @@ func slugify(title string) string { return s } -// mustParseTemplates loads admin templates from the templates/admin/ directory. +// mustParseTemplates loads admin templates from the embedded filesystem. func mustParseTemplates() *template.Template { funcs := template.FuncMap{ "splitTags": func(s string) []string { @@ -367,8 +371,8 @@ func mustParseTemplates() *template.Template { return tags }, } - // Load all .html files from templates/admin/ directory - tmpl, err := template.New("admin").Funcs(funcs).ParseGlob("templates/admin/*.html") + // Parse templates from embedded filesystem + tmpl, err := template.New("admin").Funcs(funcs).ParseFS(adminTemplates, "templates/*.html") if err != nil { panic(fmt.Sprintf("failed to parse admin templates: %v", err)) } diff --git a/internal/admin/templates/base.html b/internal/admin/templates/base.html new file mode 100644 index 0000000..f88bba6 --- /dev/null +++ b/internal/admin/templates/base.html @@ -0,0 +1,34 @@ +{{define "base"}} + + + + + + + Admin — {{.Title}} + + + + + + + +
+ {{if eq .ContentTemplate "list-content"}}{{template "list-content" .}}{{end}} + {{if eq .ContentTemplate "form-content"}}{{template "form-content" .}}{{end}} + {{if eq .ContentTemplate "error-content"}}{{template "error-content" .}}{{end}} +
+ + + +{{end}} \ No newline at end of file diff --git a/internal/admin/templates/error.html b/internal/admin/templates/error.html new file mode 100644 index 0000000..36a4a8a --- /dev/null +++ b/internal/admin/templates/error.html @@ -0,0 +1,7 @@ +{{define "error-content"}} +
+

Error

+

{{.Message}}

+

Go back

+
+{{end}} diff --git a/internal/admin/templates/form.html b/internal/admin/templates/form.html new file mode 100644 index 0000000..1b577c9 --- /dev/null +++ b/internal/admin/templates/form.html @@ -0,0 +1,62 @@ +{{define "form-content"}} +

{{.Title}}

+
+ + + + + + + + +

Comma-separated list of tags.

+ + + +
+ +
+ + Cancel +
+
+ + + + +{{end}} diff --git a/internal/admin/templates/list.html b/internal/admin/templates/list.html new file mode 100644 index 0000000..561e317 --- /dev/null +++ b/internal/admin/templates/list.html @@ -0,0 +1,40 @@ +{{define "list-content"}} +

Posts

+ {{if .Posts}} + + + + + + + + + + + {{range .Posts}} + + + + + + + {{end}} + +
TitleDateTags
{{.Title}}{{.Date}} + {{if .Tags}} +
+ {{range (splitTags .Tags)}}{{.}}{{end}} +
+ {{end}} +
+
+ Edit +
+ +
+
+
+ {{else}} +
No posts yet. Create one.
+ {{end}} +{{end}} -- cgit v1.3