模板缓存是什么?

huangapple go评论89阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2022年9月26日 03:32:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/73847331.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定