英文:
Pass data between templates
问题
我有一个简单的情况,其中一个模板 (text/templates)
包含另一个模板,像这样:
`index.html`
{{ template "image_row" . }}
`image_row.html`
{{ define "image_row" }}
在这里添加内容
{{ end }}
现在我想重用 image_row 模板。假设我想传递一个简单的数字,以便根据这个数字构建行。
我想要的是这样的(其中 5 是额外的参数):
index.html
{{ template "image_row" . | 5 }}
在这种情况下,我该如何实现这个目标?
英文:
I have simple case, where a templates (text/templates)
includes another like this
`index.html`
{{ template "image_row" . }}
`image_row.html`
{{ define "image_row" }}
To stuff here
{{ end }}
Now I want to reuse the image row template. Let's say I would like to pass a simple number, so that the image_row template builds up rows according to this number
I'd like to have something like that (where 5 is the additional argument)
index.html
{{ template "image_row" . | 5 }}
How could I achieve that in this case?
答案1
得分: 7
我不确定是否存在一种内置的解决方案来传递多个参数给模板调用,但是如果没有的话,你可以定义一个函数来合并其参数并将它们作为单个切片值返回,然后你可以注册该函数并在模板调用中使用它。
类似这样:
func args(vs ...interface{}) []interface{} { return vs }
t, err := template.New("t").Funcs(template.FuncMap{"args":args}).Parse...
然后,在你的 index.html
中,你可以这样做:
{{ template "image_row" args . 5 }}
然后在你的 image_row
模板中,你可以使用内置的 index
函数来访问参数,就像这样:
{{ define "image_row" }}
在这里插入内容 {{index . 0}} {{index . 1}}
{{ end }}
链接:https://play.golang.org/p/gkdtvvJ1bb
英文:
I'm not sure whether there exists a builtin solution for passing multiple arguments to a template invocation but, in case there isn't one, you could define a function that merges its arguments and returns them as a single slice value, then you can register that function and use it in the template invocation.
Something like:
func args(vs ...interface{}) []interface{} { return vs }
t, err := template.New("t").Funcs(template.FuncMap{"args":args}).Parse...
Then, in your index.html
, you would do this:
{{ template "image_row" args . 5 }}
And then inside your image_row
template you can access the arguments with the builtin index
function like this:
{{ define "image_row" }}
To stuff here {{index . 0}} {{index . 1}}
{{ end }}
答案2
得分: 4
这个没有内置的方法。你可以添加一个函数来创建一个映射,并在子模板中使用它:
func argsfn(kvs ...interface{}) (map[string]interface{}, error) {
if len(kvs)%2 != 0 {
return nil, errors.New("args requires even number of arguments.")
}
m := make(map[string]interface{})
for i := 0; i < len(kvs); i += 2 {
s, ok := kvs[i].(string)
if !ok {
return nil, errors.New("even args to args must be strings.")
}
m[s] = kvs[i+1]
}
return m, nil
}
将这个函数添加到模板中,像这样:
t := template.Must(template.New("").Funcs(template.FuncMap{"args": argsfn}).Parse(......
像这样使用它:
{{template "image_row" args "row" . "a" 5}}{{end}}
{{define "image_row"}}
{{$.row}} {{$.a}}
{{end}}
使用映射的优点是参数是“命名”的。使用另一个答案中描述的切片的优点是代码更简单。
英文:
There is no builtin for this. You can add a function that creates a map and use that in the child template:
func argsfn(kvs ...interface{}) (map[string]interface{}, error) {
if len(kvs)%2 != 0 {
return nil, errors.New("args requires even number of arguments.")
}
m := make(map[string]interface{})
for i := 0; i < len(kvs); i += 2 {
s, ok := kvs[i].(string)
if !ok {
return nil, errors.New("even args to args must be strings.")
}
m展开收缩 = kvs[i+1]
}
return m, nil
}
Add it the function to the template like this:
t := template.Must(template.New("").Funcs(template.FuncMap{"args": argsfn}).Parse(......
Use it like this:
{{template "image_row" args "row" . "a" 5}}{{end}}
{{define "image_row"}}
{{$.row}} {{$.a}}
{{end}}
The advantage of using a map is that the arguments are "named". The advantage of using a slice as described in another answer is that the code is much simpler.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论