Go 在模板之间传递数据

Go 在模板之间传递数据,go,go-templates,Go,Go Templates,我有一个简单的例子,其中一个模板(text/templates)包括另一个类似的 `index.html` {{ template "image_row" . }} `image_row.html` {{ define "image_row" }} To stuff here {{ end }} 现在我想重用图像行模板。假设我想传递一个简单的数字,以便image_行模板根据这个数字构建行 我想要这样的东西(其中5是附加参数) index.html {{ template "i

我有一个简单的例子,其中一个模板
(text/templates)
包括另一个类似的

`index.html`

{{ template "image_row" . }}


`image_row.html`

{{ define "image_row" }}

   To stuff here

{{ end }}
现在我想重用图像行模板。假设我想传递一个简单的数字,以便image_行模板根据这个数字构建行

我想要这样的东西(其中5是附加参数)

index.html

{{ template "image_row" . | 5 }}

在这种情况下,我如何才能做到这一点呢?

我不确定是否存在一种内置解决方案,可以将多个参数传递给模板调用,但如果没有,您可以定义一个函数来合并其参数并将其作为单个切片值返回,然后可以注册该函数并在模板调用中使用它

比如:

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\u行
模板中,您可以使用内置的
索引
函数访问参数,如下所示:

{{ define "image_row" }}

   To stuff here {{index . 0}} {{index . 1}}

{{ end }}
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}}

此功能没有内置功能。您可以添加创建映射的函数,并在子模板中使用该函数:

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
}
像这样使用它:

{{ define "image_row" }}

   To stuff here {{index . 0}} {{index . 1}}

{{ end }}
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}}


使用映射的优点是参数是“命名的”。如另一个答案中所述,使用切片的优点是代码要简单得多。

请澄清:您的问题是关于
文本/模板
?因为
text/tempate
允许嵌套模板定义。这是否可以与
ParseFiles
一起使用?
ParseFiles
ParseGlob
。。。不管你如何解析模板,只要你用
Funcs
方法注册了func,生成的模板就可以访问该func。如果你指的是函数
template.ParseFiles
,而不是方法
*template.ParseFiles
,那么不是,因为您无法引用尚未注册的func。因此,您需要首先创建一个
模板。使用
模板创建一个
模板。新建
,然后注册您想要使用的函数,然后在该模板上调用
ParseFiles
方法。首先,感谢您的帮助,很抱歉让这个问题变得更加复杂。就我的情况而言,它不起作用,我在这里举了一个不起作用的例子,但我认为这是正确的方向,我迟早会找到解决方案,我想:)@SOFe取决于你的意思。例如,你是否特别关注特定的值类型?如果您正在传递非指针值,那么并发使用应该是安全的,如果另一方面,您正在传递指针值,那么您可能会遇到问题,但是Go的
sync
包为您提供了足够的工具来实现并发安全解决方案。