golang web框架 gin 中template模板内容实时更新原理

golang web框架 gin 中template模板内容实时更新原理

先来看看template的使用方法

router := gin.Default()
router.GET("/", IndexApi)
//LoadHTMLFiles(templates...)
router.LoadHTMLGlob("templates/**/*")
func IndexApi(c *gin.Context) {
    c.HTML(http.StatusOK, "index.html", gin.H{"user": "User"})
    return
}

当访问根目录的时候,会直接显示index.html里的内容, 当我们不关闭golang程序直接更改模板文件的内容的时候会发现再次访问根目录的时候页面内容已经更新,他自己会实时显示最新的内容,由此可知他每一次请求都会去读取本地文件,但是这样做是不是极大的降低了网页的访问速度呢?经过查看gin的源代码,发现gin代码会区分识别debug模式和release模式,当运行在debug模式下每次访问页面都会去重新加载模板,方便代码调试,当正式发布的时候只有在第一次启动的时候去读取模板。

代码如下:

func (engine *Engine) LoadHTMLFiles(files ...string) {
    //这里判断为debug模式运行的时候实例化HTMLDebug这个结构体
    //这个结构体里的每次调用Instance方法会去重新读取模板
    if IsDebugging() {
        engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims}
        return
    }

    templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...))
    engine.SetHTMLTemplate(templ)
}
// release直接读取缓存
func (r HTMLProduction) Instance(name string, data interface{}) Render {
    return HTML{
        Template: r.Template,
        Name:     name,
        Data:     data,
    }
}
// debug每次都会读取
func (r HTMLDebug) Instance(name string, data interface{}) Render {
    return HTML{
        Template: r.loadTemplate(),
        Name:     name,
        Data:     data,
    }
}
func (r HTMLDebug) loadTemplate() *template.Template {
    if r.FuncMap == nil {
        r.FuncMap = template.FuncMap{}
    }
    if len(r.Files) > 0 {
        return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseFiles(r.Files...))
    }
    if r.Glob != "" {
        return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseGlob(r.Glob))
    }
    panic("the HTML debug render was created without files or glob pattern")
}

调用代码:

func (c *Context) HTML(code int, name string, obj interface{}) {
    //在这里调用HTMLRender接口的Instance方法
    //在上面的代码中可以看出这个接口的实现在Debug和Release中不一样,
    //在debug模式下每次调用都会调用io去重新读取模板文件的内容
    instance := c.engine.HTMLRender.Instance(name, obj)
    // 在这里面将HTML结构体里的内容进行渲染
    c.Render(code, instance)
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值