在Journey源碼分析二:總體啓動流程
中提到了模板編譯,這裏詳細說下啓動流程數據庫
看下templates.Generate()
源碼:ide
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()
的源碼:post
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)
源碼:ui
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)
源碼:this
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)
作最終編譯。lua
模板編譯方面更細節的東西我就沒什麼興趣了,你們有興趣能夠本身研究下,歡迎交流^_^code