Golang:自定义模板“块”功能?

tp5buhyn  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(210)

我想知道是否可以使用自定义函数作为Golang模板的模板block。下面的代码显示了一个例子。

{{ custom_func . }}
This is content that "custom_func" should do something with.
{{ end }}

用例有点特殊和非标准。基本上,我希望模板作者能够在考虑换行符等的情况下传入大块文本,并将整个文本块传递给函数。我可以这样做:

{{ custom_func "This is a lot of text\n with many lines etc." }}

但这对模板作者来说并不是很友好。他们的最终目标是写出这样的东西:

Author is writing something normal...

{{ note }}
But would like to wrap this content as a "note".

Which when passed to the "note" function, will wrap the content with appropriate divs etc.
{{ end }}

基本上,我正在尝试一个实验,看看我是否可以用纯go模板实现类似于“markdown/reStructuredText”的内容。
最终我可能需要为此编写一个适当的PEG解析器,但我想先看看这是否可行。

cwxwcias

cwxwcias1#

函数的字符串参数可以用双引号"或反引号'括起来。
模板中用反勾号 Package 的字符串常量被称为 raw string constants,它们的工作方式与Go语言源代码中的raw string常量类似:可以包含换行符(不能包含转义序列)。
所以如果你在参数中使用反勾号,你就有可能得到你想要的结果。
例如,a.tmpl

START
{{ note `a
b\t
c
d`}}
END

要加载和执行模板的应用程序:

t := template.Must(template.New("").Funcs(template.FuncMap{
    "note": func(s string) string { return "<note>\n" + s + "\n</note>" },
}).ParseFiles("a.tmpl"))

if err := t.ExecuteTemplate(os.Stdout, "a.tmpl", nil); err != nil {
    panic(err)
}

这将输出:

START
<note>
a
b\t
c
d
</note>
END

如果你在Go语言源代码中定义模板,这就有点麻烦了,就像你在模板文本中使用了反勾号(因为你想写多行),你不能在一个原始字符串文字中嵌入反勾号,你必须打破文字,并将反勾号连接起来。
在Go语言源文件中执行此操作的示例:

func main() {
    t := template.Must(template.New("").Funcs(template.FuncMap{
        "note": func(s string) string { return "<note>\n" + s + "\n</note>" },
    }).Parse(src))

    if err := t.Execute(os.Stdout, nil); err != nil {
        panic(err)
    }
}

const src = `START
{{ note ` + "`" + `a
b\t
c
d` + "`" + `}}
END
`

这将输出相同的结果,请在Go Playground上尝试。

相关问题