Sibert
(Sibert)
February 11, 2019, 6:47am
1
I have ONE layout that I want to populate with MANY other sub pages. I am also trying to change this content dynamically.
The code works as expected but I cannot change the content. The content remains the same. Seems to fetch first match. no matter what the passing template is. Does not work even with hardcoded file names.
Main layout
{{define "layout"}}
<html>
<body>
{{ template "content" }}
</body>
</html>
{{end}}
Sub template 1 - index.gohtml
{{ define "content" }}
<h1 style="color: red;">Page 1!</h1>
{{ end }}
Sub template 2 - about.gohtml
{{ define "content" }}
<h1 style="color: blue;">Page 2!</h1>
{{ end }}
The Go code
package main
import (
"html/template"
"net/http"
"strings"
)
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("templates/*.gohtml"))
}
func main() {
http.HandleFunc("/", index)
http.ListenAndServe(":8080", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
path := strings.Trim(r.URL.Path, "/")
switch path {
case "":
path = ("index.gohtml")
default:
path = (path + ".gohtml")
}
err := tpl.ExecuteTemplate(w, "layout", path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
I have also tried to ParseFiles before Execute with no luck. Any tip how to do this?
Sibert
(Sibert)
February 17, 2019, 3:11pm
3
Yes. ONE layout with MANY different templates.
This code works:
var tpl *template.Template
func init() {tpl = template.Must(template.ParseGlob("templates/*.gohtml"))
}
func main() {
http.HandleFunc("/", index)
http.ListenAndServe(":8080", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
tpl.ExecuteTemplate(w, "layout", nil)
}
But as soon as I try to set another content:
var tpl *template.Template
func init() {tpl = template.Must(template.ParseGlob("templates/*.gohtml"))
}
func main() {
http.HandleFunc("/", index)
http.ListenAndServe(":8080", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
tpl, _ = template.ParseFiles("layout.gohtml", "index.gohtml")
tpl.ExecuteTemplate(w, "layout", nil)
}
Got tons of errors
2019/02/17 15:59:07 http: panic serving 127.0.0.1:52020:
runtime error: invalid memory address or nil pointer dereference etc
So any tip is welcome!
Sibert
(Sibert)
February 21, 2019, 10:35am
4
At last I got it to work, but only when not following the manuals.
Solution Part 1
Skip {{define…}} and {{end}} in templates. Weird…
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Go Web Programming</title>
</head>
<body>
layout level
{{ template "content" . }}
</body>
</html>
As well as in subtemplates…
<p>subpage</p>
Solution Part 2
I found a code snippet with AddParsTree and here is the code (simplified with no error handling)
package main
import (
"html/template"
"net/http"
"strings"
)
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("templates/*.html"))
}
func main() {
http.HandleFunc("/", index)
http.ListenAndServe(":8080", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
path := strings.Trim(r.URL.Path, "/")
switch path {
case "":
path = ("home.html")
default:
path = (path + ".html")
}
layout := tpl.Lookup("layout.html")
layout, _ = layout.Clone()
t := tpl.Lookup(path)
_, _ = layout.AddParseTree("content", t.Tree)
layout.Execute(w, "")
I do not really understand why I have to disobey the manuals to get it to work. Any comments that enlighten me will be appreciated.
system
(system)
Closed
May 22, 2019, 10:35am
5
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.