英文:
What is a template cache?
问题
我来帮你翻译一下代码的内容:
render.go:
var functions = template.FuncMap{}
var app *config.AppConfig
// NewTemplates 设置模板包的配置
func NewTemplates(a *config.AppConfig) {
app = a
}
// RenderTemplate 渲染模板
func RenderTemplate(w http.ResponseWriter, tmpl string) {
var tc map[string]*template.Template
// 如果开启了开发模式
if app.UseCache {
// 从应用配置中获取模板缓存
tc = app.TemplateCache
} else {
tc, _ = CreateTemplateCache()
}
t, ok := tc[tmpl]
if !ok {
log.Fatal("无法从模板缓存中获取模板 (render.go 的第 37 行)")
}
buf := new(bytes.Buffer)
_ = t.Execute(buf, nil)
_, err := buf.WriteTo(w)
if err != nil {
fmt.Println("在 render.go 的第 44 行将模板写入浏览器时发生错误:", err)
}
}
// CreateTemplateCache 创建模板缓存
func CreateTemplateCache() (map[string]*template.Template, error) {
myCache := map[string]*template.Template{}
pages, err := filepath.Glob("./templates/*page.html")
fmt.Println("所有匹配 '*page.html' 的页面列表:", pages)
if err != nil {
return myCache, err
}
for _, page := range pages {
name := filepath.Base(page)
fmt.Println("当前页面:", page)
fmt.Println("template.New 的返回值:", template.New(name))
ts, err := template.New(name).Funcs(functions).ParseFiles(page)
if err != nil {
return myCache, err
}
matches, err := filepath.Glob("./templates/*.layout.html")
if err != nil {
return myCache, err
}
if len(matches) > 0 {
ts, err = ts.ParseGlob("./templates/*.layout.html")
if err != nil {
return myCache, err
}
}
myCache[name] = ts
}
return myCache, nil
}
config.go:
// AppConfig 存储应用程序配置
type AppConfig struct {
UseCache bool
TemplateCache map[string]*template.Template
}
*template.Template
是一个指向模板的指针。在这段代码中,TemplateCache
是一个存储模板的缓存,它是一个 map[string]*template.Template
类型的字段。RenderTemplate
函数根据传入的模板名称从缓存中获取对应的模板,并将其渲染到 http.ResponseWriter
中。
config.go
中的 AppConfig
结构体包含了应用程序的配置信息,其中 UseCache
字段表示是否开启缓存,TemplateCache
字段是一个存储模板的缓存,类型为 map[string]*template.Template
。
这段代码中使用了依赖注入的方式,通过在 NewTemplates
函数中将应用程序配置传递给 app
变量,然后在 RenderTemplate
函数中使用该配置。依赖注入是一种设计模式,用于解耦组件之间的依赖关系,使得代码更加可测试和可维护。
指针是一种特殊的数据类型,它存储了一个变量的内存地址。在这段代码中,app
是一个指向 AppConfig
结构体的指针,通过使用指针可以在函数之间共享数据,避免了数据的复制和传递。在 Go 语言中,指针常用于传递大型的数据结构,以提高性能和效率。
希望这些解释对你有帮助!如果你还有其他问题,请随时提问。
英文:
I'm confused with this code that I wrote it by watching golang course. Please explain me what will *template.Template
contain? It is called template cache so what is this exactly? And why config.go
has TemplateCache
field and RenderTemplate
refers to it? I guess it is dependency injection and so far dependency injection and pointers are the most confusing things for me in golang
render.go
var functions = template.FuncMap{}
var app *config.AppConfig
// NewTemplates sets the config for the template package
func NewTemplates(a *config.AppConfig) {
app = a
}
// RenderTemplate
func RenderTemplate(w http.ResponseWriter, tmpl string) {
var tc map[string]*template.Template
// if statement enables development mode
if app.UseCache {
//get the template cache from the app config
tc = app.TemplateCache
} else {
tc, _ = CreateTemplateCache()
}
t, ok := tc[tmpl]
if !ok {
log.Fatal("couldnt get template from template cache in render.go (37)")
}
buf := new(bytes.Buffer)
_ = t.Execute(buf, nil)
_, err := buf.WriteTo(w)
if err != nil {
fmt.Println("Error writing template to browser in render.go (44)", err)
}
}
// CreateTemplateCache creates template cache as a map
func CreateTemplateCache() (map[string]*template.Template, error) {
myCache := map[string]*template.Template{}
pages, err := filepath.Glob("./templates/*page.html")
fmt.Println("List of all pages that matches '*page.html': ", pages)
if err != nil {
return myCache, err
}
for _, page := range pages {
name := filepath.Base(page)
fmt.Println("Page is currently", page)
fmt.Println("template.New return value: ", template.New(name))
ts, err := template.New(name).Funcs(functions).ParseFiles(page)
if err != nil {
return myCache, err
}
matches, err := filepath.Glob("./templates/*.layout.html")
if err != nil {
return myCache, err
}
if len(matches) > 0 {
ts, err = ts.ParseGlob("./templates/*.layout.html")
if err != nil {
return myCache, err
}
}
myCache[name] = ts
}
return myCache, nil
}
config.go
// AppConfig holds the application config
type AppConfig struct {
UseCache bool
TemplateCache map[string]*template.Template
}
答案1
得分: 5
根据pkg.go.dev上的文档,Template是一个包含一个名为Tree的字段的结构体,其类型为*parse.Tree。如果我们进入parse包,我们可以看到:
Tree是单个解析模板的表示。
至于你关于TemplateCache
是什么的问题,它就是字面意思。
在计算机中,缓存是一个高速数据存储层,用于存储数据的子集。
因此,TemplateCache
用于存储模板以供将来使用和访问。当RenderTemplate
运行时,它会从头开始使用html/tmpl文件构建模板,将其转换为Go可以处理和渲染的格式(template.Template
)。
一个简单的RenderTemplate
函数的版本将在每个请求中的所有不同处理程序中调用它,每次它们被调用时都会调用它,但是RenderTemplate
函数的作用是在应用程序的开始时只调用一次,在main.go
中构建所有模板并将它们存储在TemplateCache
中以供将来使用。
英文:
According to the docs at pkg.go.dev Template is a struct that contains one field named Tree with type *parse.Tree. If we go to parse package we see that
> Tree is the representation of a single parsed template.
As to your question about what TemplateCache
is, it's as it sounds.
> In computing, a cache is a high-speed data storage layer which stores a subset of data
So the TemplateCache
stores template for future use and access. When RenderTemplate
runs, it builds the template from scratch using the html/tmpl files to a format (template.Template
) that Go can work with and render.
A naive version of the RenderTemplate
function would be calling it after every request in all the different handlers each time they are called but what the RenderTemplate
function does is that it's getting called only once at the beginning of the application in main.go
and build all the templates and store them in the TemplateCache
for future use.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论