我有一个Web应用程序,我正在尝试按照以下建议预先缓存我的模板: https://golang.org/doc/articles/wiki/#tmp_10
目前这就是我正在做的。 (我提供了示例模板帮助器功能,以使您有所了解) (请注意,App对象是应用程序的其余部分,用于处理实际的Web服务和数据库内容)
///a function that the template can pass a different arg
func functiontakingarguments(arg1 string, arg2 string) (firststring string) {
return arg1
}
func (app *App) defaultTemplHelpers(w http.ResponseWriter, r *http.Request) template.FuncMap {
m := template.FuncMap{
"sessionfoo": func() bool {
//some function
return hasUserSession(r)
},
"bar": functiontakingarguments,
}
/*
Many many more template functions
*/
return m
}
func myPageWithLayout(app *App, w http.ResponseWriter, r *http.Request, path string, file string, layout string, funcs template.FuncMap, data map[string]interface{}) {
logger.Debugf("rendering template with layout %+v at path %+v, page %+v", layout, path, file)
t, err := template.New(file).Funcs(funcs).ParseFiles(
filepath.Join(templatesPath, path, file),
filepath.Join(templatesPath, "layouts", layout),
)
if err != nil {
logger.Errorf("error rendering html template %+v: %+v", file, err.Error())
http.Error(w, "error", http.StatusInternalServerError)
return
}
//previously used to establish default template data
templData := map[string]interface{}{}
// merge passed in data with our template data
for k, v := range data {
templData[k] = v
}
executeTemplate(w, t, templData)
}
///the following is an example of a template:
/*
apagewithfuncs.html:
<h1> Hello! </h1>
{{ functiontakingarguments "astring" "asecondstring" }}
{{ if sessionfoo }} Something to do with that session function {{else}} nevermind! {{end}}
*/
我敢打赌,您可以在这里轻松发现第一组问题。每次必须为每个请求从磁盘读取模板。
因为我有一些模板函数依赖于用户查看它们的内容或会话变量,所以我将r * http.Request传递给模板呈现函数,以便在调用我的辅助函数时,它们可以访问该请求数据。
据我所知,这意味着我无法按照先前的链接(https://golang.org/doc/articles/wiki/#tmp_10)中所述完全预缓存这些模板
因此,首先,这通常是一种不好的方法吗? (不是为了赚钱,而是其中一些代码来自另一个程序员)
第二,有没有办法使它更有效?例如,缓存其中的一部分但仍然能够使用那些辅助函数? 我很确定这整个设置会拖累我的应用程序性能,但我可能是错的。我试过一些丑陋的技巧,例如尝试(someargs ... interface {}),然后进行类型转换(是的,我是一个可怕的罪人)
答案 0 :(得分:1)
将所有每个请求状态作为参数传递给Execute。 定义一个封装每个请求状态的类型:
im2, contours, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
在模板中使用该类型:
simplevar := $(varname)
val = $($(simplevar)-value)
有了这些更改,可以在程序启动时对模板进行一次解析。假设模板指针存储在包级变量type data struct {
r *http.Request
Data map[string]interface{}
}
func (d *data) SessionFoo() bool {
return hasUserSession(d.r)
}
中,您可以像这样执行它:
<h1> Hello! </h1>
{{ functiontakingarguments "astring" "asecondstring" }}
{{ if $.SessionFoo }} Something to do with that session function {{else}} nevermind! {{end}}
templData["x"] is {{$.Data.x}}