Go 优化html/模板组合
我想看看是否有更好(更快、更有组织)的方法在围棋中分割我的模板。我非常喜欢使用html/模板(或其包装器),因为我信任它的安全模型Go 优化html/模板组合,go,Go,我想看看是否有更好(更快、更有组织)的方法在围棋中分割我的模板。我非常喜欢使用html/模板(或其包装器),因为我信任它的安全模型 现在我使用template.ParseGlob解析init()中的所有模板文件 我将template.Funcs应用于生成的模板 我在每个模板中设置一个$title(即listing_payment.tmpl)并将其传递给内容模板 我知道html/template会在解析后将模板缓存在内存中 我的处理程序只调用t.ExecuteTemplate(w,“name.t
- 现在我使用
解析template.ParseGlob
init()中的所有模板文件
- 我将template.Funcs应用于生成的模板
- 我在每个模板中设置一个
(即$title
)并将其传递给内容模板listing_payment.tmpl
- 我知道
会在解析后将模板缓存在内存中html/template
- 我的处理程序只调用
,并且不对每个请求进行任何愚蠢的解析t.ExecuteTemplate(w,“name.tmpl”,map[string]接口{})
- 我从多个片段组成模板(我觉得这有点笨重),如下所示:
{{ $title := "Page Title" }} {{ template "head" $title }} {{ template "checkout" }} {{ template "top" }} {{ template "sidebar_details" . }} {{ template "sidebar_payments" }} {{ template "sidebar_bottom" }} <div class="bordered-content"> ... {{ template "listing_content" . }} ... </div> {{ template "footer"}} {{ template "bottom" }}
{{$title:=“页面标题”} {{template“head”$title} {{模板“签出”} {{模板“顶部”} {{模板“侧边栏_详细信息”。} {{模板“边栏付款”} {{template“sidebar_bottom”} ... {{模板“列出内容”} ... {{模板“页脚”} {{模板“底部”}
{{template“name”}
标记会导致潜在的每请求性能问题?在压力测试较重的页面时,我看到很多写断管道错误。这可能只是由于套接字超时(即,在编写器可以完成之前关闭套接字),而不是某种按请求组合(否则请更正!)
在Reddit的帮助下,我成功地找到了一种相当合理(且性能良好)的方法,可以:
- 使用内容块构建布局
- 创建有效“扩展”这些布局的模板
- 用其他模板填充块(脚本、边栏等)
<html>
<head>
{{ template "title" .}}
</head>
<body>
{{ template "scripts" . }}
{{ template "sidebar" . }}
{{ template "content" . }}
<footer>
...
</footer>
</body>
{{ define "title"}}<title>Index Page</title>{{ end }}
// We must define every block in the base layout.
{{ define "scripts" }} {{ end }}
{{ define "sidebar" }}
// We have a two part sidebar that changes depending on the page
{{ template "sidebar_index" }}
{{ template "sidebar_base" }}
{{ end }}
{{ define "content" }}
{{ template "listings_table" . }}
{{ end }}
从最初的基准测试(使用
wrk
)来看,当涉及到重载时,它的性能似乎要高一些,这可能是因为我们没有在每个请求中传递一个完整的ParseGlob
模板。这也使模板的编写变得简单得多。我是个新手,正在尝试解决这个问题。data
参数只是发送到模板的参数散列吗?@wuliwong因为数据是一个接口{}
它可以是任何你想要的。我通常会传递一个map[string]接口{}
,其中映射键是“user”、“itemList”等。一位同事指出,.ExecuteTemplate
采用与.Execute
相同的方式获取参数。我的问题在别处。我正在将参数传递给嵌套模板。谢谢你的回复!如果您有用户角色,并且每个角色都有不同的内容菜单,该怎么办?为每个角色创建不同的模板[“index.html”]?好的,那么唯一的解决方案似乎是使用web组件的方法,以便在不创建新模板的情况下加载每个角色的子内容。@cespinoza要么在渲染模板时加载,要么在Go 1.6中使用新块功能-
var templates map[string]*template.Template
var ErrTemplateDoesNotExist = errors.New("The template does not exist.")
// Load templates on program initialisation
func init() {
if templates == nil {
templates = make(map[string]*template.Template)
}
templates["index.html"] = template.Must(template.ParseFiles("index.tmpl", "sidebar_index.tmpl", "sidebar_base.tmpl", "listings_table.tmpl", "base.tmpl"))
...
}
// renderTemplate is a wrapper around template.ExecuteTemplate.
func renderTemplate(w http.ResponseWriter, name string, data map[string]interface{}) error {
// Ensure the template exists in the map.
tmpl, ok := templates[name]
if !ok {
return ErrTemplateDoesNotExist
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
tmpl.ExecuteTemplate(w, "base", data)
return nil
}