【问题标题】:Golang template global dot within a template that's given a value from range模板中的 Golang 模板全局点,该模板中的值来自范围
【发布时间】:2015-04-13 21:14:02
【问题描述】:

我的设置:

base.tmpl

{{define "base"}} ...basic hmtl boilerplate ...{{end}}
{{define "post"}}
    {{.ID}} {{.Username}} etc... 
    {{if $.User.Admin}}
        <...admin controls...>
    {{end}}
{{end}}

index.tmpl

{{template "base" . }}
{{define "content"}}
    Stuff......
    {{range .Posts }}
        {{template "post" . }}
    {{end}}
{{end}}

但我明白了

$.User.Admin 不是 db.Post 的字段

如何从未提供的模板中的“全局”点值中获取值?美元。显然不起作用。

我只是在该范围内发布帖子,但我添加了一个新页面来查看各个帖子,并且不想更新帖子单独显示的每个区域。

更新:模板是这样执行的

func Index(rw http.ResponseWriter, req *http.Request) {
    g := GetGlobal(rw, req) // Gets logged in user info, adds branch/version info etc
    ... Get posts from the DB ...
    if err := Templates["index.tmpl"].Execute(rw, g); err != nil {
        Log.Println("Error executing template", err.Error())
    }
}

全局结构如下所示:

type Global struct {
    User     db.User
    Users    []db.User
    EditUser db.User
    Session  *sessions.Session
    Error    error
    Posts    []db.Post
    Post     db.Post

    DoRecaptcha bool
    Host        string
    Version     string
    Branch      string
}

模板是这样加载的:

Templates[filename] = template.Must(template.ParseFiles("templates/"+filename, "templates/base.tmpl"))

【问题讨论】:

  • 可能会考虑添加一些其他标签。您的问题特定于您使用的模板解决方案。我知道 Go 很好,但对这个主题一无所知。
  • 我使用的是内置的 html/template 包。我找不到与之相关的既定标签,所以我没有打扰 e: 找到一个
  • 是的,我很容易找到这个包。感谢您的编辑,将来会有所帮助。 Go 缺乏 SO 采用,但问题几乎都在一般的“go”桶中,就像 .NET 一样,所有公共库都有标签。
  • 是的,这在很大程度上取决于 Golang 设法将多少内容打包到他们的标准库中。如果我找不到任何东西,我可能只需要在我的帖子中添加一个 *db.User 字段并在渲染页面之前填写它。不是很优雅,但它会工作。
  • 如何将值传递给模板?通过地图?您也可以发布该代码吗?例如template.Execute(...)

标签: go go-html-template


【解决方案1】:

调用模板会创建一个新范围:

模板调用不会从其调用点继承变量。

所以你有三个选择:

  1. 在帖子中添加对父级的引用(正如您在上一条评论中所说的那样)
  2. 创建一个通过闭包引用变量的函数(isAdmin):

    template.New("test").Funcs(map[string]interface{}{
        "isAdmin": func() bool {
            return true // you can get it here
        },
    }).Parse(src)
    

    这种方法的缺点是每次都必须解析模板。

  3. 创建一个新函数,它可以构造一个引用父级的帖子,而无需修改原始数据。例如:

    template.New("test").Funcs(map[string]interface{}{
        "pair": func(x, y interface{}) interface{} {
            return struct { First, Second interface{} } { x, y }
        },
    }).Parse(src)
    

    你可以这样使用它:

    {{range .Posts }}
        {{template "post" pair $ . }}
    {{end}}
    

    另一种选择是创建一个dict 函数:Calling a template with several pipeline parameters

【讨论】:

    猜你喜欢
    • 2016-11-06
    • 1970-01-01
    • 2017-11-30
    • 2017-05-22
    • 1970-01-01
    • 2017-07-07
    • 2019-06-06
    • 2021-05-03
    • 2021-09-14
    相关资源
    最近更新 更多