英文:
Golang template global dot within a template that's given a value from range
问题
我的设置:
base.tmpl
{{define "base"}} ...基本的HTML模板...{{end}}
{{define "post"}}
{{.ID}} {{.Username}} 等...
{{if $.User.Admin}}
<...管理员控制...>
{{end}}
{{end}}
index.tmpl
{{template "base" .}}
{{define "content"}}
内容......
{{range .Posts}}
{{template "post" .}}
{{end}}
{{end}}
但是我得到了以下错误信息:
$.User.Admin不是db.Post的字段
在没有给定的模板中,如何从“全局”点值中获取值?$.显然不起作用。
我之前只是在范围内使用了post,但我添加了一个新页面来查看单个帖子,并且不希望单独更新每个显示帖子的区域。
更新:模板的执行方式如下:
func Index(rw http.ResponseWriter, req *http.Request) {
g := GetGlobal(rw, req) // 获取已登录用户信息,添加分支/版本信息等
... 从数据库获取帖子 ...
if err := Templates["index.tmpl"].Execute(rw, g); err != nil {
Log.Println("执行模板时出错", err.Error())
}
}
Global结构如下:
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"))
英文:
My setup:
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}}
But I get
>$.User.Admin is not a field of db.Post
How can I get the values from the "global" dot value within a template that isn't given it? $. clearly doesn't work.
I was just having the post within the range, but I added a new page to view individual posts and would like to not update each area that posts are displayed individually.
Update: Templates are executed like so
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())
}
}
The Global struct looks like:
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 are loaded like so:
Templates[filename] = template.Must(template.ParseFiles("templates/"+filename, "templates/base.tmpl"))
答案1
得分: 4
调用模板会创建一个新的作用域:
> 模板调用不会继承调用点的变量。
所以你有三个选项:
-
在帖子中添加对父级的引用(就像你在最后一条评论中说的那样)。
-
创建一个通过闭包引用变量的函数(
isAdmin
):template.New("test").Funcs(map[string]interface{}{ "isAdmin": func() bool { return true // 你可以在这里获取它 }, }).Parse(src)
这种方法的缺点是你需要每次解析模板。
-
创建一个新的函数,可以构造一个带有对父级的引用的帖子,而无需修改原始数据。例如:
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
函数:https://stackoverflow.com/questions/18276173/calling-a-template-with-several-pipeline-parameters/18276968#18276968
英文:
Invoking a template creates a new scope:
> A template invocation does not inherit variables from the point of its invocation.
So you have three options:
-
Add a reference to the parent in the post (as you said you're doing in your last comment)
-
Create a function (
isAdmin
) that references the variable through closure:template.New("test").Funcs(map[string]interface{}{ "isAdmin": func() bool { return true // you can get it here }, }).Parse(src)
The downside of this approach is you have to parse the template every time.
3. Create a new function which can construct a post that has a reference to the parent without having to modify the original data. For example:
template.New("test").Funcs(map[string]interface{}{
"pair": func(x, y interface{}) interface{} {
return struct { First, Second interface{} } { x, y }
},
}).Parse(src)
And you could use it like this:
{{range .Posts }}
{{template "post" pair $ . }}
{{end}}
Another option is to make a dict
function: https://stackoverflow.com/questions/18276173/calling-a-template-with-several-pipeline-parameters/18276968#18276968
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论