更新嵌套模板Golang

I am trying to change contents dynamically. But the content remains the same. Seems to fetch first match. no matter what the template is. Does not work even with hardcoded file names. The code works as expected but the content cannot be changed.

Main layout

{{define "layout"}}
    <html>
    <body>
        {{ template "content" }}
    </body>
    </html>
{{end}}

Sub template 1

{{ define "content" }}

<h1 style="color: red;">Page 1!</h1>

{{ end }}

Sub template 2

{{ 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. What am I doing wrong?

dongli4274
matlabmann 嵌套模板在golang.org/pkg/html/template中曾经被提及。我找不到解决我问题的任何东西。
一年多之前 回复
dtqjbbr5283
dtqjbbr5283 您只是将路径作为数据传递到模板,这没有任何意义。请阅读text/template和html/template文件。
一年多之前 回复
dongxin8392
dongxin8392 客户端收到<h1style=“color:red;”>INDEX!</h1>,但是路径变量是正确的“index.gohtml”和“about.gohtml”。在其他浏览器中使用任一路径打开都显示相同的行为。
一年多之前 回复
douxin2002
douxin2002 客户得到什么结果?您是否已确认问题不是浏览器缓存了内容?
一年多之前 回复

2个回答

我相信



解析模板后调整路径为时已晚。</ p>

可以工作(尽管我不确定这里是否是最优雅的解决方案)正在使用 AddParseTree </ code>方法:</ p>


AddParseTree为 具有给定名称的模板,并且
将其与t关联。 如果该模板尚不存在,它将
创建一个新模板。 如果模板确实存在,它将被替换。</ p>
</ blockquote>

根据您要 Parse </ code>解析相关模板的条件,应用于您的案例 文件(子模板1或2),然后在执行之前将其与 AddParseTree </ code>添加到 tpl </ code>。</ p>
</ div>

展开原文

原文

Adjusting the path after the templates have been parsed is too late, I believe.

What could work (though I'm not sure is the most elegant solution here) is using the AddParseTree method:

AddParseTree adds parse tree for template with given name and associates it with t. If the template does not already exist, it will create a new one. If the template does exist, it will be replaced.

Applied to your case, based on the condition you would Parse the relevant template file (sub template 1 or 2), and then add it with AddParseTree to tpl, before you execute it.

dongrou5254
dongrou5254 任何技巧或链接如何实现?
一年多之前 回复

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>

And in subtemplates as well...

<h1 style="color: red;">Page 1!</h1>

Solution Part 2

I found a code snippet with AddParsTree as Eli mentioned 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.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐