Golang中html/template能否实现block继承功能
Golang中html/template能否实现block继承功能 大家好,我认为通过代码来解释我的问题会更清楚:
{{define "base"}}
<h1>An example template</h1>
{{block "sidebar" .}}
<p>My default sidebar content</p>
{{end}}
{{end}}
<!-- child1.html -->
{{template "base" .}}
<!--
我希望此页面的侧边栏显示:
<p>My default sidebar content</p>
-->
<!--
答案:什么都不做即可
-->
<!-- child2.html -->
{{template "base" .}}
<!--
我希望此页面显示:
<p>My default sidebar content</p>
<p>My custom sidebar content</p>
-->
{{define "sidebar"}}
<!-- 答案:??? -->
{{end}}
<!-- child3.html -->
{{template "base" .}}
<!--
我希望此页面的侧边栏显示:
<p>My custom sidebar content</p>
<p>My default sidebar content</p>
-->
{{define "sidebar"}}
<!-- 答案:??? -->
{{end}}
我在 Django[1] 和 Laravel[2] 中使用过这个特定功能,想知道如何使用 Go 模板来实现它。
谢谢!
[1] 如何覆盖模板 | Django 文档 | Django [2] Blade 模板 - Laravel - 为 Web 工匠打造的 PHP 框架
更多关于Golang中html/template能否实现block继承功能的实战教程也可以访问 https://www.itying.com/category-94-b0.html
不幸的是,我认为这并没有涵盖我的具体问题。
据我理解,您想要一个基础模板,并在基础模板内为每个页面使用模板。我曾尝试实现这一点,但我放弃了。现在我正在页面级别使用“组件”。这种方法不错,但并非我最初想要的方式。我发现这已经足够好,并且更容易复用组件。
我不太确定我完全理解你想要什么,但类似这样的东西怎么样?
package main
import (
"fmt"
"html/template"
"os"
)
var baseTemplate = `{{define "base"}}
<h1>An example template</h1>
<p>My default sidebar content</p>
{{block "sidebar" .}}
{{end}}
{{end}}`
var childTemplate = `{{template "base" .}}`
var childTemplateWithCustom = `{{template "base" .}}
{{define "sidebar"}}<p>Custom sidebar template</p>{{end}}`
func main() {
baseTmpl := template.Must(template.New("baseTemplate").Parse(baseTemplate))
childTmpl, _ := template.Must(baseTmpl.Clone()).Parse(childTemplate)
fmt.Println("No custom content:")
childTmpl.Execute(os.Stdout, nil)
childTmplWithCustom, _ := template.Must(baseTmpl.Clone()).Parse(childTemplateWithCustom)
fmt.Println("Custom content:")
childTmplWithCustom.Execute(os.Stdout, nil)
}
… 其输出为:
No custom content:
<h1>An example template</h1>
<p>My default sidebar content</p>
Custom content:
<h1>An example template</h1>
<p>My default sidebar content</p>
<p>Custom sidebar template</p>
如果你愿意,可以在 Go Playground 上运行它。同时,查看关于与其他模板共享模板构建块的文档:
template package - text/template - Go Packages
Package template implements data-driven templates for generating textual output.
他们称之为“驱动模板”,但其基本思想是可重用的基础模板,你可以通过 .Clone 在其他模板中使用它们。
在Go语言的html/template中,可以通过block和define的组合来实现类似Django和Laravel的模板继承功能。以下是针对你三个场景的解决方案:
1. 基础模板 (base.html)
{{define "base"}}
<!DOCTYPE html>
<html>
<body>
<h1>An example template</h1>
{{block "sidebar" .}}
<p>My default sidebar content</p>
{{end}}
</body>
</html>
{{end}}
2. child1.html - 使用默认侧边栏
{{template "base" .}}
<!--
渲染结果:
<h1>An example template</h1>
<p>My default sidebar content</p>
-->
3. child2.html - 追加内容到默认侧边栏
{{define "sidebar"}}
{{template "base.sidebar" .}}
<p>My custom sidebar content</p>
{{end}}
{{template "base" .}}
<!--
渲染结果:
<h1>An example template</h1>
<p>My default sidebar content</p>
<p>My custom sidebar content</p>
-->
4. child3.html - 在默认内容前添加自定义内容
{{define "sidebar"}}
<p>My custom sidebar content</p>
{{template "base.sidebar" .}}
{{end}}
{{template "base" .}}
<!--
渲染结果:
<h1>An example template</h1>
<p>My custom sidebar content</p>
<p>My default sidebar content</p>
-->
5. Go代码示例
package main
import (
"html/template"
"os"
)
func main() {
// 解析所有模板文件
tmpl := template.Must(template.ParseFiles(
"base.html",
"child1.html",
"child2.html",
"child3.html",
))
// 执行child2.html
err := tmpl.ExecuteTemplate(os.Stdout, "child2.html", nil)
if err != nil {
panic(err)
}
}
6. 更复杂的继承示例
<!-- base.html -->
{{define "base"}}
<html>
<head>
<title>{{block "title" .}}Default Title{{end}}</title>
</head>
<body>
{{block "content" .}}{{end}}
{{block "sidebar" .}}
<div class="default-sidebar">
<p>Default sidebar</p>
</div>
{{end}}
</body>
</html>
{{end}}
<!-- page.html -->
{{define "title"}}Custom Page Title{{end}}
{{define "sidebar"}}
<div class="custom-sidebar">
<p>Custom sidebar header</p>
{{template "base.sidebar" .}}
<p>Custom sidebar footer</p>
</div>
{{end}}
{{define "content"}}
<h1>Page Content</h1>
<p>This is the main content area.</p>
{{end}}
{{template "base" .}}
关键点:
{{block "name" .}}定义可被覆盖的区块{{define "name"}}在子模板中重新定义区块{{template "base.sidebar" .}}引用父模板中的原始内容- 所有模板必须在同一个
template.Template实例中解析
这种方式可以实现灵活的模板继承和内容覆盖,虽然语法与Django/Laravel不同,但功能上是等效的。



