Journey源码分析三:模板编译

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)做最终编译。

模板编译方面更细节的东西我就没什么兴趣了,大家有兴趣可以自己研究下,欢迎交流^_^

转载于:https://my.oschina.net/fmnisme/blog/502487

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值