0

I don't have enough credit to post a comment to this thread (Is it possible to have nested templates in Go using the standard library? (Google App Engine))

I attempted to follow the selected answer for nesting Go templates, but I still face redefinition of template error.

//contents of base.tmpl
{{define "base"}}
<!DOCTYPE html>
<html>
    <head>
    {{template "header" .}}
    {{template "head" .}}
    </head>
    <body>
    {{template "body" .}}
    </body>
</html>
{{end}}

//contents of header.tmpl
{{define "header"}}
<link rel="stylesheet" type="text/css" href="/css/bootstrap/bootstrap.min.css">
{{end}}

//contents of index.tmpl
{{template "base"}}     
{{define "head"}}{{end}}
{{define "body"}}
<table class="table table-hover">
    <thead>
        <tr>
            <th>#</th>
        <th>Status</th>
        <th>Active Hints</th>
        </tr>
</thead>

<tbody>
{{range .}}
        <tr>
            <td>{{.Id}}</td>
        <td>{{.Satus}}</td>
        <td>{{.ActiveHints}}</td>
        </tr>
{{end}}
</tbody>
</table>
{{end}}

//contents of create.tmpl
{{template "base"}}
{{define "head"}}{{end}}
{{define "body"}}
    <form class="form-horizontal" role="form">
    <div class="form-group">
        <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
        <div class="col-sm-10">
            <input type="email" class="form-control" id="inputEmail3" placeholder="Question" required>
        </div>
    </div>
{{end}}

As per the answer to other SO question, I parse each template set separately and execute them separately:

func buildTemplates() {
    tmpl := make(map[string]*template.Template)
    tmpl["index"] = template.Must(template.ParseFiles("templates/admin/base.tmpl", "templates/admin/index.tmpl", "templates/admin/header.tmpl"))
    tmpl["create"] = template.Must(template.ParseFiles("templates/admin/base.tmpl", "templates/admin/create.tmpl", "templates/admin/header.tmpl"))

    for _, v := range tmpl {
        if err := v.ExecuteTemplate(os.Stdout, "base", nil); err != nil {
        log.Fatalf("template execution: %s", err)
        }
    }
}

It compiles fine, but upon execution: 'panic: template: redefinition of template "body"' What have I done wrong?

Community
  • 1
  • 1
mvhatch
  • 127
  • 10
  • How are you calling tmpl in your handler code, given that the `tmpl` variable only exists within the `buildTemplates()` function? PS: I wrote an article on how to avoid declaring every block in each sub-template, as well as how to automatically generate the templates map instead of writing out each map key here: http://elithrar.github.io/article/approximating-html-template-inheritance/ – elithrar Jun 24 '14 at 06:36
  • It compiles and executes fine with `go version go1.3 darwin/amd64` – creack Jun 24 '14 at 15:51
  • elithrar - in your article: "If you define two blocks and both have content, the application will panic when it attempts to parse the template files (on startup, most likely)." I have 2 templates (index and create) that define "body". Does this mean that there is no way achieve this design pattern? – mvhatch Jun 24 '14 at 19:18
  • creack - I have go1.2.2 darwin/amd64; I will try updating and seeing if that helps. – mvhatch Jun 24 '14 at 19:19
  • creack - go1.3 darwin/amd64 made no difference (the release notes showed no changes to that package anyway). – mvhatch Jun 24 '14 at 20:16
  • @mvhatch - *only* if you parse both `index` and `create` into the same template (which, from the code you've posted, you have not). Your `ExecuteTemplate` function should call `index` or `create` and not `base`, though. – elithrar Jun 25 '14 at 03:25

0 Answers0