为了账号安全,请及时绑定邮箱和手机立即绑定

更新嵌套模板 Golang

更新嵌套模板 Golang

Go
浮云间 2023-06-05 17:52:17
我正在尝试动态更改内容。但内容保持不变。似乎要获取第一场比赛。不管模板是什么。即使使用硬编码文件名也不起作用。代码按预期工作,但内容无法更改。主要布局{{define "layout"}}    <html>    <body>        {{ template "content" }}    </body>    </html>{{end}}子模板 1{{ define "content" }}<h1 style="color: red;">Page 1!</h1>{{ end }}子模板 2{{ define "content" }}<h1 style="color: blue;">Page 2!</h1>{{ end }}围棋代码package mainimport (    "html/template"    "net/http"    "strings")var tpl *template.Templatefunc 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    }}我也曾尝试在执行之前执行 ParseFiles,但没有成功。我究竟做错了什么?
查看完整描述

3 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

我认为,在解析模板后调整路径为时已晚。

可行的方法(虽然我不确定这里是否是最优雅的解决方案)是使用以下AddParseTree方法:

AddParseTree 为具有给定名称的模板添加解析树并将其与 t 相关联。如果模板尚不存在,它将创建一个新模板。如果模板确实存在,它将被替换。

适用于您的情况,根据您将Parse相关模板文件(子模板 1 或 2)的条件,然后在执行之前将其添加到AddParseTreeto 。tpl


查看完整回答
反对 回复 2023-06-05
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

最后我让它工作了,但只有在不遵循手册的情况下。


解决方案第 1 部分


跳过模板中的 {{define}} 和 {{end}}。诡异的...


<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>

在子模板中也是如此......


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

解决方案第 2 部分

我找到了一个带有 AddParsTree 的代码片段,这是代码(经过简化,没有错误处理)


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, "")

我真的不明白为什么我必须不遵守手册才能让它工作。任何启发我的评论将不胜感激。


查看完整回答
反对 回复 2023-06-05
?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

我遇到了同样的问题并以这种方式解决了它:


这对我来说适用于{{ define "content1" }}...{{ end }}语法,但你必须给你的模板唯一的名称:content1和content2。


我制作了一个用于处理模板内容的包。


package templates


import (

    "html/template"

    "log"

    "net/http"

)


var tmpls *template.Template


// LoadTemplates parses a template folder

func LoadTemplates(tmplPath string) {

    tmpls = template.Must(template.ParseGlob(tmplPath))

}


// ExecTmpl executes a template and writes it

func ExecTmpl(w http.ResponseWriter, tmpl string, data interface{}) {

    tmpls.ExecuteTemplate(w, tmpl, data)

}


// ExecTmplTree combines and executes two templates

func ExecTmplTree(w http.ResponseWriter, outer, inner string, data interface{}) {

    layout, err := tmpls.Lookup(outer).Clone()

    if err != nil || layout == nil {

        log.Fatal("ExecTmplTree: Could not get a copy of template", outer)

    }

    content, err := tmpls.Lookup(inner).Clone()

    if err != nil || content == nil {

        log.Fatal("ExecTmplTree: Could not get a copy of template", inner)

    }

    _, err = layout.AddParseTree("content", content.Tree)

    if err != nil {

        log.Fatal("ExecTmplTree: Templates could not be combined.")

    }

    layout.Execute(w, data)

}


然后我调用函数如下(在 main.go 或其他地方):


// call first to load templates from the folder where your templates are stored

// you might need fit the file ending, too, I simply use .html for html-templates

func init() {

    templates.LoadTemplates("web/templates/*.html")

}


// write a basic template without nesting

func exampleHandler(w http.ResponseWriter, r *http.Request) {

    templates.ExecTmplTree(w, "content1", "messageForm", nil)

}


// write nested templates. here, index is the outer template

// and code is the inner

func indexHandler(w http.ResponseWriter, r *http.Request) {

    templates.ExecTmplTree(w, "layout", "content1", nil)

}


查看完整回答
反对 回复 2023-06-05
  • 3 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信