admin管理员组文章数量:1279115
I am using the Echo framework in Golang to serve HTML templates, but I have an issue where the title updates correctly. However, the content remains the same for both the home (/) and about (/about) pages.
When I navigate to /about, the title changes to "About | Application", but the content is still the same as the home page (/) instead of showing the correct about page content.
Project Structure
/app
/handlers
home.go
about.go
/views
renderer.go
/templates
/layouts
main.html
/pages
index.html
about.html
main.go
Code Implementation main.go (Entry Point)
package main
import (
"app/handlers"
"app/views"
"github/labstack/echo/v4"
"github/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Renderer = views.NewRenderer()
e.GET("/", handlers.Home)
e.GET("/about", handlers.About)
e.Static("/static", "static")
e.Logger.Fatal(e.Start(":8080"))
}
views/renderer.go (Template Renderer)
package views
import (
"html/template"
"io"
"path/filepath"
"strings"
"github/labstack/echo/v4"
)
type TemplateRenderer struct {
templates *template.Template
}
func NewRenderer() *TemplateRenderer {
funcMap := template.FuncMap{
"dict": func(values ...interface{}) map[string]interface{} {
if len(values)%2 != 0 {
panic("invalid dict call")
}
dict := make(map[string]interface{}, len(values)/2)
for i := 0; i < len(values); i += 2 {
key, ok := values[i].(string)
if !ok {
panic("dict keys must be strings")
}
dict[key] = values[i+1]
}
return dict
},
}
tmpl := template.New("").Funcs(funcMap)
layoutGlob := filepath.Join("templates", "layouts", "*.html")
pagesGlob := filepath.Join("templates", "pages", "*.html")
tmpl = template.Must(tmpl.ParseGlob(layoutGlob))
tmpl = template.Must(tmpl.ParseGlob(pagesGlob))
normalizedTemplates := template.New("").Funcs(funcMap)
for _, t := range tmpl.Templates() {
if t.Tree == nil || t.Tree.Root == nil {
continue
}
name := t.Name()
if strings.HasPrefix(name, "pages/") {
name = strings.TrimPrefix(name, "pages/")
}
name = strings.TrimSuffix(name, ".html")
_, err := normalizedTemplates.New(name).Parse(t.Tree.Root.String())
if err != nil {
panic("Failed to normalize template names: " + err.Error())
}
}
return &TemplateRenderer{
templates: normalizedTemplates,
}
}
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
handlers/home.go
package handlers
import (
"net/http"
"github/labstack/echo/v4"
)
func Home(c echo.Context) error {
return c.Render(http.StatusOK, "index", map[string]interface{}{})
}
handlers/about.go
package handlers
import (
"net/http"
"github/labstack/echo/v4"
)
func About(c echo.Context) error {
return c.Render(http.StatusOK, "about", map[string]interface{}{})
}
Templates
templates/layouts/main.html (Layout)
{{ define "layout" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ block "title" . }}{{ if .title }}{{ .title }} | Application{{ else }}Application{{ end }}{{ end }}</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<nav>
<a href="/">Home</a> | <a href="/about">About</a>
</nav>
<main>
{{ template "content" . }}
</main>
</body>
</html>
{{ end }}
templates/pages/index.html
{{ template "layout" (dict "title" "Home") }}
{{ define "content" }}
<h1>Welcome to the Home Page</h1>
<p>This is a simple multi-page app with Echo.</p>
{{ end }}
templates/pages/about.html
{{ template "layout" (dict "title" "About") }}
{{ define "content" }}
<h1>About</h1>
<p>This is a simple multi-page app with Echo.</p>
{{ end }}
Expected Behavior / should render index.html inside layout/main.html. /about should render about.html inside layout/main.html.
Actual Behavior / works as expected. /about only updates the title but keeps the content from / (Home Page).
Possible Issue I suspect that {{ template "layout" (dict "title" "About") }} in about.html is calling layout directly and rendering "index.html" content instead of its own.
I am using the Echo framework in Golang to serve HTML templates, but I have an issue where the title updates correctly. However, the content remains the same for both the home (/) and about (/about) pages.
When I navigate to /about, the title changes to "About | Application", but the content is still the same as the home page (/) instead of showing the correct about page content.
Project Structure
/app
/handlers
home.go
about.go
/views
renderer.go
/templates
/layouts
main.html
/pages
index.html
about.html
main.go
Code Implementation main.go (Entry Point)
package main
import (
"app/handlers"
"app/views"
"github/labstack/echo/v4"
"github/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Renderer = views.NewRenderer()
e.GET("/", handlers.Home)
e.GET("/about", handlers.About)
e.Static("/static", "static")
e.Logger.Fatal(e.Start(":8080"))
}
views/renderer.go (Template Renderer)
package views
import (
"html/template"
"io"
"path/filepath"
"strings"
"github/labstack/echo/v4"
)
type TemplateRenderer struct {
templates *template.Template
}
func NewRenderer() *TemplateRenderer {
funcMap := template.FuncMap{
"dict": func(values ...interface{}) map[string]interface{} {
if len(values)%2 != 0 {
panic("invalid dict call")
}
dict := make(map[string]interface{}, len(values)/2)
for i := 0; i < len(values); i += 2 {
key, ok := values[i].(string)
if !ok {
panic("dict keys must be strings")
}
dict[key] = values[i+1]
}
return dict
},
}
tmpl := template.New("").Funcs(funcMap)
layoutGlob := filepath.Join("templates", "layouts", "*.html")
pagesGlob := filepath.Join("templates", "pages", "*.html")
tmpl = template.Must(tmpl.ParseGlob(layoutGlob))
tmpl = template.Must(tmpl.ParseGlob(pagesGlob))
normalizedTemplates := template.New("").Funcs(funcMap)
for _, t := range tmpl.Templates() {
if t.Tree == nil || t.Tree.Root == nil {
continue
}
name := t.Name()
if strings.HasPrefix(name, "pages/") {
name = strings.TrimPrefix(name, "pages/")
}
name = strings.TrimSuffix(name, ".html")
_, err := normalizedTemplates.New(name).Parse(t.Tree.Root.String())
if err != nil {
panic("Failed to normalize template names: " + err.Error())
}
}
return &TemplateRenderer{
templates: normalizedTemplates,
}
}
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
handlers/home.go
package handlers
import (
"net/http"
"github/labstack/echo/v4"
)
func Home(c echo.Context) error {
return c.Render(http.StatusOK, "index", map[string]interface{}{})
}
handlers/about.go
package handlers
import (
"net/http"
"github/labstack/echo/v4"
)
func About(c echo.Context) error {
return c.Render(http.StatusOK, "about", map[string]interface{}{})
}
Templates
templates/layouts/main.html (Layout)
{{ define "layout" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ block "title" . }}{{ if .title }}{{ .title }} | Application{{ else }}Application{{ end }}{{ end }}</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<nav>
<a href="/">Home</a> | <a href="/about">About</a>
</nav>
<main>
{{ template "content" . }}
</main>
</body>
</html>
{{ end }}
templates/pages/index.html
{{ template "layout" (dict "title" "Home") }}
{{ define "content" }}
<h1>Welcome to the Home Page</h1>
<p>This is a simple multi-page app with Echo.</p>
{{ end }}
templates/pages/about.html
{{ template "layout" (dict "title" "About") }}
{{ define "content" }}
<h1>About</h1>
<p>This is a simple multi-page app with Echo.</p>
{{ end }}
Expected Behavior / should render index.html inside layout/main.html. /about should render about.html inside layout/main.html.
Actual Behavior / works as expected. /about only updates the title but keeps the content from / (Home Page).
Possible Issue I suspect that {{ template "layout" (dict "title" "About") }} in about.html is calling layout directly and rendering "index.html" content instead of its own.
Share Improve this question asked Feb 24 at 4:51 Ali ZainAli Zain 416 bronze badges1 Answer
Reset to default 0about.html and index.html both call {{ template "layout" (dict "title" "About") }}. layout.html doesn't know which specific page is being rendered, so we should pass content block correctly, we can define content before including the layout:
In your about.html:
{{ define "content" }}
<h1>About</h1>
<p>This is a simple multi-page app with Echo.</p>
{{ end }}
{{ template "layout" (dict "title" "About" "content" .) }}
in your index.html:
{{ define "content" }}
<h1>Welcome to the Home Page</h1>
<p>This is a simple multi-page app with Echo.</p>
{{ end }}
{{ template "layout" (dict "title" "Home" "content" .) }}
Update {{ template "content" . }} to {{ .content }} in main.html:
<main>
{{ .content }}
</main>
本文标签: htmlEcho Golang Template Issue Content Not Changing on Different RoutesStack Overflow
版权声明:本文标题:html - Echo Golang Template Issue: Content Not Changing on Different Routes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741293630a2370690.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论