【问题标题】:Pass data between templates [duplicate]在模板之间传递数据[重复]
【发布时间】:2017-04-15 12:25:17
【问题描述】:

我有一个简单的例子,一个模板(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 }}

在这种情况下我怎么能做到这一点?

【问题讨论】:

  • 请澄清:您的问题是关于text/template ?因为text/tempate 允许嵌套模板定义。

标签: go go-templates


【解决方案1】:

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

类似:

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

【讨论】:

  • 这是否可以与ParseFiles一起使用?
  • ParseFiles, ParseGlob... 不管你如何解析模板,只要你用Funcs方法注册了func,生成的模板就可以访问到那个功能。
  • 如果您指的是函数template.ParseFiles 而不是方法*Template.ParseFiles 那么,因为您不能引用尚未注册的函数。所以你需要先用template.New创建一个template.Template,然后注册你要使用的函数,然后在那个模板上调用ParseFiles方法。
  • 首先,感谢您的帮助,很抱歉让这件事变得更加复杂。对于我的情况,它不起作用我在这里做了一个不起作用的例子play.golang.org/p/lJrfBs--d5,但我认为这是正确的方向,我想我迟早会找到解决方案:)
  • @SOFe 取决于您的意思,您是否对特定值类型有特别关注?如果你传递的是非指针值,那么它应该是安全的并发使用,另一方面,如果你传递的是指针值,那么你可能会遇到问题,但是 Go 的 sync 包为你提供了足够的工具实施并发安全的解决方案。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多