Change contents of a nested template?


(Sibert) #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?


(Johan Dahl) #2

Is this what you are trying to accomplish?

https://www.htmlgoodies.com/beyond/reference/nesting-templates-with-go-web-programming.html


(Sibert) #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!