fix: parse templates individually to prevent content block overwrite
Some checks failed
CI / lint (push) Failing after 19s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / docker (push) Has been skipped

Root cause: ParseFS with wildcard html/*.html caused all {{define "content"}}

blocks to overwrite each other — last alphabetically (register.html) won for

all pages. Now each page is parsed separately with base.html as its own template.

Also fix footer link: GitHub → Gitea project page.
This commit is contained in:
2026-06-04 16:57:34 +03:00
parent 2f1f1ef7d6
commit 21d48200f5
2 changed files with 25 additions and 17 deletions

View File

@@ -348,7 +348,7 @@
</header> </header>
<main><div class="container">{{template "content" .}}</div></main> <main><div class="container">{{template "content" .}}</div></main>
<footer> <footer>
<p>MrixsCraft Server &copy; 2026 · <a href="https://github.com/Mrixs/MrixsCraft-server">GitHub</a></p> <p>MrixsCraft Server &copy; 2026 · <a href="https://gitea.mrixs.me/Mrixs/MrixsCraft">Gitea</a></p>
</footer> </footer>
<script> <script>
// Update nav based on auth state // Update nav based on auth state

View File

@@ -23,14 +23,14 @@ type pageData struct {
// Handler serves template-rendered pages. // Handler serves template-rendered pages.
type Handler struct { type Handler struct {
db *database.DB db *database.DB
cfg *config.Config cfg *config.Config
tmpl *template.Template templates map[string]*template.Template
} }
// NewHandler creates a new templates handler and parses embedded templates. // NewHandler creates a new templates handler and parses embedded templates.
func NewHandler(db *database.DB, cfg *config.Config) *Handler { func NewHandler(db *database.DB, cfg *config.Config) *Handler {
h := &Handler{db: db, cfg: cfg} h := &Handler{db: db, cfg: cfg, templates: make(map[string]*template.Template)}
h.parseTemplates() h.parseTemplates()
return h return h
} }
@@ -65,28 +65,36 @@ func (h *Handler) profilePage(w http.ResponseWriter, r *http.Request) {
h.render(w, "profile.html", pageData{Title: "Профиль"}) h.render(w, "profile.html", pageData{Title: "Профиль"})
} }
// render executes the base layout template which calls {{template "content" .}} // render executes the named page template.
// to inject the named page content.
func (h *Handler) render(w http.ResponseWriter, page string, data pageData) { func (h *Handler) render(w http.ResponseWriter, page string, data pageData) {
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
if h.tmpl == nil { tmpl, ok := h.templates[page]
http.Error(w, "Templates not loaded", http.StatusInternalServerError) if !ok {
log.Printf("Template not found: %s", page)
http.Error(w, "Template not found", http.StatusInternalServerError)
return return
} }
if err := h.tmpl.ExecuteTemplate(w, "base.html", data); err != nil { if err := tmpl.Execute(w, data); err != nil {
log.Printf("Template error (base.html → %s): %v", page, err) log.Printf("Template error (%s): %v", page, err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError) http.Error(w, "Internal Server Error", http.StatusInternalServerError)
} }
} }
// ── Template parsing ─────────────────────────────────────────── // ── Template parsing ───────────────────────────────────────────
// parseTemplates parses each page template individually by cloning the base
// layout and adding the specific page content. This avoids the issue where
// multiple {{define "content"}} blocks in wildcard-parsed files overwrite
// each other (last alphabetically wins).
func (h *Handler) parseTemplates() { func (h *Handler) parseTemplates() {
tmpl, err := template.New("").Funcs(template.FuncMap{}).ParseFS(templateFS, "html/*.html") pages := []string{"index.html", "login.html", "register.html", "profile.html"}
if err != nil { for _, page := range pages {
log.Printf("Template parse error: %v", err) tmpl, err := template.New("").Funcs(template.FuncMap{}).ParseFS(templateFS, "html/base.html", "html/"+page)
return if err != nil {
log.Printf("Template parse error (%s): %v", page, err)
continue
}
h.templates[page] = tmpl
log.Printf("Loaded template: %s", page)
} }
h.tmpl = tmpl
log.Println("Loaded embedded HTML templates")
} }