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

How can I override a template block with an empty template?

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

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

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

不知何故 Go 似乎认为这个定义是 "Zero" 并且仍然会呈现默认内容,除非我将任何非空白内容放入定义中。

我找到了 this issue on the Golang repo which describes the very same thing nicely in a 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 中的错误还是方法有缺陷?我是否需要做任何不同的事情才能重新定义块以使其呈现为空?

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

Templates can be redefined in successive calls to Parse, before the first use of Execute on t or any associated template. A template definition with a body containing only white space and comments is considered empty and will not replace an existing template's body. This allows using Parse to add new named template definitions without overwriting the main template body.

所以你不能"erase"一个已经定义的模板(你不能将它的内容替换为空)。

如果您 "conditionally" 需要它,则使用 {{if}} 操作来决定是否调用模板。或者你可以在模板中放置一个 {{if}} ,模板本身可以选择不渲染任何东西。在这种情况下,您必须确保传递控制模板呈现内容的正确参数。

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