持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情 ,祝福祖国,生日快乐 :)
Hugo的组件设计
架构图可以帮助我们从全局视角理解Hugo的架构设计。 现在让我们更近一步,从模块的角度来观察Hugo架构的细节
配置和语言的关系
Hugo提供了强大的配置功能,如配置文件、配置目录、配置主题等等。 构建站点过程中,只要是你能想到的定制化需求,基本都能通过配置实现。
为了满足不同的定制化需求,Hugo的思路是首先要处理好多配置文件之间的关系,所以需要合并一些配置项,这样就需要大小写不敏感。 定制化只是一小部分,其它的通用信息,就用默认配置来进行说明。
支持多语言是常见需求,现在好多软件遵循的策略就是国际化优先。 那Hugo是怎么理解语言和配置的关系呢?
在个人站点实例中,我们在config.toml中和语言相关的配置如下:
defaultContentLanguage = 'zh'
[languages]
[languages.zh]
languageName = '中文'
contentDir = 'content'
weight = 1
[languages.en]
languageName = 'English'
contentDir = 'content.en'
weight = 2
可以配置默认语言,支持的多语言有中文和英语。
那这样看来,配置应该包含语言。 也就是说语言应该是配置结构体中的一个字段。 而事实是这样的吗? 让我们还是从Hugo游乐场源码出发,来一探究竟。
在此之前,我们先从架构图中寻找线索:
可以看到,最终创建Language的地方是在DepsCfg,并不是Config。 这和我们的直觉是相反的,让我们来看看关键的config.Provider,DepsCfg和Language相关代码片断。
config.Provider
// Provider provides the configuration settings for Hugo.
type Provider interface {
...
Get(key string) any
Set(key string, value any)
...
}
可以看出,Provider接口提供了Get和Set方法,就像一个key/value仓库。
那语言相关的配置同样也存储在了Provider里面。
DepsCfg
// DepsCfg contains configuration options that can be used to configure Hugo
// on a global level, i.e. logging etc.
// Nil values will be given default values.
type DepsCfg struct {
// The language to use.
Language *langs.Language
// The configuration to use.
Cfg config.Provider
...
}
DepsCfg中包含了config.Provider以及Language。
创建站点的时候,直接传入的就是DepsCfg:
// newSite creates a new site with the given configuration.
func newSite(cfg deps.DepsCfg) (*Site, error) {
...
}
在调用创建站点前,DepsCfg就已经把Language准备好了:
func createSitesFromConfig(cfg deps.DepsCfg) ([]*Site, error) {
...
languages := getLanguages(cfg.Cfg)
for _, lang := range languages {
...
cfg.Language = lang
s, err = newSite(cfg)
...
}
return sites, nil
}
而从Language结构体可以看出:
// Language manages specific-language configuration.
type Language struct {
Lang string
Weight int // for sort
// Global config.
// For internal use.
Cfg config.Provider
...
}
Language是包含了Cfg config.Provider的。 也就是说Language和Config的关系实际上是包含关系,并不像我们上面感受到的那样。 仔细一想,合情合理。 Config专注提供配置key/value仓库管理服务,而Language和Site是一一对应的,需要其它配置信息补充说明。