fix: parse templates individually to prevent content block overwrite
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:
@@ -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 © 2026 · <a href="https://github.com/Mrixs/MrixsCraft-server">GitHub</a></p>
|
<p>MrixsCraft Server © 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
|
||||||
|
|||||||
@@ -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")
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user