如何使用空模板覆盖模板块?

时间:2017-09-12 10:48:30

标签: go go-templates

使用text/html我在我的基本模板中定义了block,其中包含默认内容。在某些情况下,我希望这个块是空的,所以我想我可以重新定义它的名字并使它包含如下内容:

{{ block "something" . }}
    <h1>Default content</h1>
{{ end }}

// later in a place that does not want "something" ...
{{ define "something" }}{{ end }}

不知怎的,Go似乎认为这个定义是&#34; Zero&#34;除非我将任何非空白内容放入定义中,否则仍将呈现默认内容。

我发现this issue on the Golang repoa Playground example中很好地描述了同样的事情:

package main

import (
    "fmt"
    "os"
    "runtime"
    "text/template"
)

func main() {

    fmt.Printf("Version: %q\n", runtime.Version())

    t, err := template.New("master").Parse(`{{block "area51" .}}Original Content{{end}}`)
    if err != nil {
        panic(err)
    }
    t, err = t.New("other_template").Parse(`{{define "area51"}}{{end}}`)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Output:\n")
    if err := t.ExecuteTemplate(os.Stdout, "master", nil); err != nil {
        panic(err)
    }

    fmt.Printf("\n")

}

奇怪的是,问题提到它是固定的(如果我理解正确的话,它会落在1.8.1中),但它对我不起作用,对1.8.1+和1.9都不起作用。

这是Golang中的错误还是方法存在缺陷?我是否需要以不同的方式执行任何操作才能重新定义块以使其呈现为空?

1 个答案:

答案 0 :(得分:2)

这是预期的行为。这在Template.Parse()

中记录
  

在第一次使用Execute on t或任何相关模板之前,可以在连续调用Parse时重新定义模板。 主体仅包含空格和注释的模板定义被视为空,不会替换现有模板的主体。这允许使用Parse添加新的命名模板定义而不覆盖主模板主体。

因此,您无法“擦除”已定义的模板(您无法将其内容替换为空)。

如果您“有条件地”需要它,请使用{{if}}操作来决定是否要调用模板。或者,您可以在模板中放置{{if}},模板本身可以选择不渲染任何内容。在这种情况下,您必须确保传递控制模板将呈现的内容的正确参数。

P.S。如果您正在使用HTML模板,则应始终使用html/template而不是text/template,因为前者提供与包text/template相同的接口,但也提供上下文转义以生成HTML输出安全反对代码注入。