在模板之间传递数据

时间:2017-04-15 12:25:18

标签: go go-templates

我有一个简单的案例,模板(text/templates)包含另一个这样的

`index.html`

{{ template "image_row" . }}


`image_row.html`

{{ define "image_row" }}

   To stuff here

{{ end }}

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

我希望有类似的东西(其中5是附加参数)

index.html

{{ template "image_row" . | 5 }}

在这种情况下我怎么能实现呢?

2 个答案:

答案 0 :(得分: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_row模板中,您可以使用内置index函数访问参数,如下所示:

{{ define "image_row" }}

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

{{ end }}

https://play.golang.org/p/gkdtvvJ1bb

答案 1 :(得分:3)

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

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

Run it in the playground

使用地图的好处是参数是“命名的”。使用另一个答案中描述的切片的优点是代码更简单。