您的位置:首页 > 编程语言 > Go语言

Journey源码分析三:模板编译

2015-09-07 18:44 477 查看
Journey源码分析二:整体启动流程
中提到了模板编译,这里详细说下启动流程

看下
templates.Generate()
源码:

func Generate() error {
compiledTemplates.Lock()
defer compiledTemplates.Unlock()
// 首先清除模板(主题可能已经改变了)
compiledTemplates.m = make(map[string]*structure.Helper)
// 编译所有模板文件。
err := checkThemes()
if err != nil {
return err
}
// If the dev flag is set, watch the theme directory and the plugin directoy for changes
// TODO: It seems unclean to do the watching of the plugins in the templates package. Move this somewhere else.
if flags.IsInDevMode {
// Get the currently used theme path
activeTheme, err := database.RetrieveActiveTheme()
if err != nil {
return err
}
currentThemePath := filepath.Join(filenames.ThemesFilepath, *activeTheme)
// Create watcher
err = watcher.Watch([]string{currentThemePath, filenames.PluginsFilepath}, map[string]func() error{".hbs": Generate, ".lua": plugins.Load})
if err != nil {
return err
}
}
return nil
}

模板编译主要在
checkThemes()
函数中:

func checkThemes() error {
// Get currently set theme from database
// 从数据库获取当前数据库
activeTheme, err := database.RetrieveActiveTheme()
if err != nil {
return err
}
currentThemePath := filepath.Join(filenames.ThemesFilepath, *activeTheme)
err = compileTheme(currentThemePath)
if err == nil {
return nil
}
// 如果当前主题编译失败,则尝试默认主题(promenade)
err = compileTheme(filepath.Join(filenames.ThemesFilepath, "promenade"))
if err == nil {
// Update the theme name in the database
err = methods.UpdateActiveTheme("promenade", 1)
if err != nil {
return err
}
return nil
}
// 如果默认主题也编译失败,则遍历所有可用的主题,选取第一个可用的。
allThemes := GetAllThemes()
for _, theme := range allThemes {
err = compileTheme(filepath.Join(filenames.ThemesFilepath, theme))
if err == nil {
// Update the theme name in the database
err = methods.UpdateActiveTheme(theme, 1)
if err != nil {
return err
}
return nil
}
}
return errors.New("Couldn't find a theme to use in " + filenames.ThemesFilepath)
}

看下
compileTheme(currentThemePath)
源码:

func compileTheme(themePath string) error {
// 检查主题目录是否存在
if _, err := os.Stat(themePath); os.IsNotExist(err) {
return errors.New("Couldn't find theme files in " + themePath + ": " + err.Error())
}
err := filepath.Walk(themePath, inspectTemplateFile)
if err != nil {
return err
}
// Check if index and post templates are compiled
if _, ok := compiledTemplates.m["index"]; !ok {
return errors.New("Couldn't compile template 'index'. Is index.hbs missing?")
}
if _, ok := compiledTemplates.m["post"]; !ok {
return errors.New("Couldn't compile template 'post'. Is post.hbs missing?")
}
// Check if pagination and navigation templates have been provided by the theme.
// If not, use the build in ones.
if _, ok := compiledTemplates.m["pagination"]; !ok {
err = compileFile(filepath.Join(filenames.HbsFilepath, "pagination.hbs"))
if err != nil {
log.Println("Warning: Couldn't compile pagination template.")
}
}
if _, ok := compiledTemplates.m["navigation"]; !ok {
err = compileFile(filepath.Join(filenames.HbsFilepath, "navigation.hbs"))
if err != nil {
log.Println("Warning: Couldn't compile navigation template.")
}

}
return nil
}

上面代码的核心代码是
err := filepath.Walk(themePath, inspectTemplateFile)
,该方法遍历主题目录中的文件,并调用
inspectTemplateFile()
函数,看下
inspectTemplateFile()
的源码:

func inspectTemplateFile(filePath string, info os.FileInfo, err error) error {
if !info.IsDir() && filepath.Ext(filePath) == ".hbs" {
err := compileFile(filePath)
if err != nil {
return err
}
}
return nil
}

如果
filePath
是文件并且以
.hbs
结尾则编译它。看下
compileFile(filePath)
源码:

func compileFile(fileName string) error {
// 编译模板文件
helper, err := createTemplateFromFile(fileName)
if err != nil {
return err
}
// 将模板放入到全局变量compiledTemplates.m中去。
compiledTemplates.m[helper.Name] = helper
return nil
}

看下
createTemplateFromFile(fileName)
源码:

func createTemplateFromFile(filename string) (*structure.Helper, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
fileNameWithoutExtension := helpers.GetFilenameWithoutExtension(filename)
// 如果同名的模板已经存在compiledTemplates.m字典中则报错。
if compiledTemplates.m[fileNameWithoutExtension] != nil {
return nil, errors.New("Error: Conflicting .hbs name '" + fileNameWithoutExtension + "'. A theme file of the same name already exists.")
}
helper := compileTemplate(data, fileNameWithoutExtension)
return helper, nil
}

该函数主要是读取模板文件,然后调用
compileTemplate(data, fileNameWithoutExtension)
做最终编译。

模板编译方面更细节的东西我就没什么兴趣了,大家有兴趣可以自己研究下,欢迎交流^_^
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  journey go