如何使用go的template模版
tmpl, err = tmpl.New("page_content").Parse(fmt.Sprintf(`{{template "%s" .}}`, contentBlockName)) |
- 创建新块:
tmpl.New("page_content")
:在模板对象tmpl
中定义一个新的、名为"page_content"
的块。- 这个块是动态的,之前并不存在,是运行时根据传入的
contentBlockName
创建的。
- 填充内容:
Parse(fmt.Sprintf(
{{template "%s" .}}, contentBlockName))
:- 使用
fmt.Sprintf
生成一个模板指令:{{template "home_content" .}}
。 - 这个指令表示:在当前模板上下文中,渲染名为
home_content
的块,并将当前数据(.
)传递给它。
- 使用
- 换句话说,
home_content
块的内容会被插入到page_content
块中。
- 动态替换:
- 假设基础模板
base.html
中包含:<body>
{{template "page_content" .}}
</body>
- 在执行模板时,
page_content
块会被替换为home_content
块的内容。
- 假设基础模板
为什么复制模板
- 避免污染原始模板:
- 如果不克隆模板,而是直接修改原始模板,会影响后续的模板调用。
- 例如,如果在一次请求中动态定义了
page_content
块,其他请求可能也会无意中使用这个定义,导致逻辑混乱。
- 支持并发调用:
- 在高并发场景中,多个请求可能同时调用
renderTemplate
函数。 - 每个请求都需要一个独立的模板实例,以避免数据竞争和冲突。
- 在高并发场景中,多个请求可能同时调用
整体流程
- 模板加载:
- 加载基础模板(
base.html
)和页面模板(如home.html
)。 - 页面模板中定义了具体的块(如
home_content
)。
- 加载基础模板(
- 动态块定义:
- 克隆模板对象,创建一个新的块(如
page_content
)。 - 动态填充这个块的内容,指向传入的
contentBlockName
(如home_content
)。
- 克隆模板对象,创建一个新的块(如
- 模板渲染:
- 使用基础模板
base.html
进行渲染。 - 在渲染过程中,
page_content
块会被替换为home_content
块的内容,最终填充到HTML页面的<body>
区域。
- 使用基础模板
总结
通过动态创建和填充块,这种方法实现了模板的灵活性和可复用性:
- 灵活性:可以根据不同的请求动态渲染不同的内容块。
- 可复用性:基础模板保持不变,页面模板可以定义多个块,按需替换。
这种设计模式在需要动态生成HTML页面的Web应用中非常常见,能够有效提升开发效率和代码可维护性。