应用程序启动后是否可以重新加载html模板?

时间:2016-04-30 07:01:25

标签: go

现在我正在将所有模板解析为变量,如下所示:

var templates = template.New("Template")

func LoadTemplates() {
    filepath.Walk("view/", func(path string, info os.FileInfo, err error) error {
        if strings.HasSuffix(path, ".html") {
            templates.ParseFiles(path)
        }
        return nil
    })
}

func Render(w http.ResponseWriter, tmplName string, data interface{}) {
    if err := templates.ExecuteTemplate(w, tmplName, data); err != nil {
        log.Println(err)
    }
}

因此,如果我进行任何更改,我需要重新启动整个应用程序。我有什么方法可以做到这一点,以便在他们做出改变时反映出来的改变

2 个答案:

答案 0 :(得分:9)

在开发/处于调试模式时,完全可以在每个请求上重新加载模板。

您可以定义一个接口和两个“模板执行器”,如此

const templateGlob = "templates/*.html"
const debug = true

var executor TemplateExecutor

func main() {
    if debug {
        executor = DebugTemplateExecutor{templateGlob}

    } else {
        executor = ReleaseTemplateExecutor{
            template.Must(template.ParseGlob(templateGlob)),
        }
    }

    http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
        executor.ExecuteTemplate(w, "test.html", nil)
    })

    http.ListenAndServe(":3000", nil)
}

包装template.Execute()。在运行时选择你想要的那个,例如

{{1}}

如果您需要在生产中进行热重新加载,我建议您查看目录以进行更改,而不是在每次请求时进行编译。

答案 1 :(得分:2)

是的,可以在运行时重新加载(html或文本)模板。

只要您正在阅读模板的文件夹可供应用程序访问,您只需重复模板解析即可。

你可以这样做:

var templates = template.New("Template")

func folderChanged(folder string) bool {
    // todo: implement filesystem watcher here
    return true
}

func ReloadTemplates(templateFolder string) {

    newTemplates, err := LoadTemplates(templateFolder)
    if err != nil {
        log.Println("Unable to load templates: %s", err)
        return
    }

    // override existing templates variable
    templates = newTemplates
}

func LoadTemplates(folder string) (*template.Template, error) {
    template := template.New("Template")

    walkError := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
        if strings.HasSuffix(path, ".html") {
            _, parseError := template.ParseFiles(path)
            if parseError != nil {
                return parseError
            }

        }

        return nil

    })

    return template, walkError
}

func Render(w http.ResponseWriter, tmplName string, data interface{}) {
    templateFolder := "view"
    if folderChanged(templateFolder) {
        ReloadTemplates(templateFolder)
    }

    if err := templates.ExecuteTemplate(w, tmplName, data); err != nil {
        log.Println(err)
    }

}

如果您正在使用类似./view - 文件夹的相对路径,则只有在您执行应用程序的目录具有此类子文件夹时,它才会起作用。如果不是这种情况,我会建议使用相对于用户主目录的路径或类似的东西。