Skip to content

Commit

Permalink
Allow themes to define output formats, media types and params
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Mar 19, 2018
1 parent bf2dac3 commit a22b1a7
Show file tree
Hide file tree
Showing 8 changed files with 501 additions and 20 deletions.
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@
name = "github.com/muesli/smartcrop"
branch = "master"


[[constraint]]
name = "github.com/sanity-io/litter"
version = "1.1.0"
15 changes: 8 additions & 7 deletions commands/hugo.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,14 @@ func InitializeConfig(running bool, doWithCommandeer func(c *commandeer) error,
// Init file systems. This may be changed at a later point.
osFs := hugofs.Os

config, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{Fs: osFs, Src: source, Name: cfgFile})
var dir string
if source != "" {
dir, _ = filepath.Abs(source)
} else {
dir, _ = os.Getwd()
}

config, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{Fs: osFs, Src: source, WorkingDir: dir, Name: cfgFile})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -358,12 +365,6 @@ func InitializeConfig(running bool, doWithCommandeer func(c *commandeer) error,
config.Set("publishDir", destination)
}

var dir string
if source != "" {
dir, _ = filepath.Abs(source)
} else {
dir, _ = os.Getwd()
}
config.Set("workingDir", dir)

if contentDir != "" {
Expand Down
9 changes: 7 additions & 2 deletions helpers/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,16 @@ func ReplaceExtension(path string, newExt string) string {
// AbsPathify creates an absolute path if given a relative path. If already
// absolute, the path is just cleaned.
func (p *PathSpec) AbsPathify(inPath string) string {
return AbsPathify(p.workingDir, inPath)
}

// AbsPathify creates an absolute path if given a working dir and arelative path.
// If already absolute, the path is just cleaned.
func AbsPathify(workingDir, inPath string) string {
if filepath.IsAbs(inPath) {
return filepath.Clean(inPath)
}

return filepath.Join(p.workingDir, inPath)
return filepath.Join(workingDir, inPath)
}

// GetLayoutDirPath returns the absolute path to the layout file dir
Expand Down
155 changes: 151 additions & 4 deletions hugolib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package hugolib
import (
"errors"
"fmt"
"path/filepath"

"io"
"strings"
Expand All @@ -28,9 +29,10 @@ import (

// ConfigSourceDescriptor describes where to find the config (e.g. config.toml etc.).
type ConfigSourceDescriptor struct {
Fs afero.Fs
Src string
Name string
Fs afero.Fs
Src string
WorkingDir string
Name string
}

func (d ConfigSourceDescriptor) configFilenames() []string {
Expand Down Expand Up @@ -85,7 +87,16 @@ func LoadConfig(d ConfigSourceDescriptor) (*viper.Viper, error) {
return v, err
}

if err := loadThemeConfig(d, v); err != nil {
return v, err
}

if err := loadLanguageSettings(v, nil); err != nil {
return v, err
}

return v, nil

}

func loadLanguageSettings(cfg config.Provider, oldLangs helpers.Languages) error {
Expand Down Expand Up @@ -201,6 +212,142 @@ func loadLanguageSettings(cfg config.Provider, oldLangs helpers.Languages) error
return nil
}

func loadThemeConfig(d ConfigSourceDescriptor, v1 *viper.Viper) error {

theme := v1.GetString("theme")
if theme == "" {
return nil
}

themesDir := helpers.AbsPathify(d.WorkingDir, v1.GetString("themesDir"))
configDir := filepath.Join(themesDir, theme)

var (
configPath string
exists bool
err error
)

// Viper supports more, but this is the sub-set supported by Hugo.
for _, configFormats := range []string{"toml", "yaml", "yml", "json"} {
configPath = filepath.Join(configDir, "config."+configFormats)
exists, err = helpers.Exists(configPath, d.Fs)
if err != nil {
return err
}
if exists {
break
}
}

if !exists {
// No theme config set.
return nil
}

v2 := viper.New()
v2.SetFs(d.Fs)
v2.AutomaticEnv()
v2.SetEnvPrefix("hugo")
v2.SetConfigFile(configPath)

err = v2.ReadInConfig()
if err != nil {
return err
}

const (
paramsKey = "params"
languagesKey = "languages"
menuKey = "menu"
)

for _, key := range []string{"params", "outputformats", "mediatypes"} {
mergeStringMapKeepLeft(key, v1, v2)
}

themeLower := strings.ToLower(theme)
themeParamsNamespace := paramsKey + "." + themeLower
// Set namespaced params

if v2.IsSet(paramsKey) && !v1.IsSet(themeParamsNamespace) {
// Set it in the default store to make sure it gets in the same or
// behind the others.
v1.SetDefault(themeParamsNamespace, v2.Get(paramsKey))
}

// Only add params and new menu entries, we do not add language definitions.
if v1.IsSet(languagesKey) && v2.IsSet(languagesKey) {
v1Langs := v1.GetStringMap(languagesKey)
for k, _ := range v1Langs {
mergeStringMapKeepLeft(languagesKey+"."+k+"."+paramsKey, v1, v2)
}
v2Langs := v2.GetStringMap(languagesKey)
for k, _ := range v2Langs {
if k == "" {
continue
}
langParamsKey := languagesKey + "." + k + "." + paramsKey
langParamsThemeNamespace := langParamsKey + "." + themeLower
// Set namespaced params
if v2.IsSet(langParamsKey) && !v1.IsSet(langParamsThemeNamespace) {
v1.SetDefault(langParamsThemeNamespace, v2.Get(langParamsKey))
}

langMenuKey := languagesKey + "." + k + "." + menuKey
if v2.IsSet(langMenuKey) {
// Only add if not in the main config.
v2menus := v2.GetStringMap(langMenuKey)
for k, v := range v2menus {
menuEntry := menuKey + "." + k
menuLangEntry := langMenuKey + "." + k
if !v1.IsSet(menuEntry) && !v1.IsSet(menuLangEntry) {
v1.Set(menuLangEntry, v)
}
}
}

}
}

// Add menu definitions from theme not found in project
if v2.IsSet("menu") {
v2menus := v2.GetStringMap(menuKey)
for k, v := range v2menus {
menuEntry := menuKey + "." + k
if !v1.IsSet(menuEntry) {
v1.SetDefault(menuEntry, v)
}
}
}

return nil

}

func mergeStringMapKeepLeft(key string, v1, v2 *viper.Viper) {

if !v1.IsSet(key) {
if v2.IsSet(key) {
v1.SetDefault(key, v2.Get(key))
}
return
}

if !v2.IsSet(key) {
return
}

m1 := v1.GetStringMap(key)
m2 := v2.GetStringMap(key)

for k, v := range m2 {
if _, found := m1[k]; !found {
m1[k] = v
}
}
}

func loadDefaultSettingsFor(v *viper.Viper) error {

c, err := helpers.NewContentSpec(v)
Expand Down Expand Up @@ -281,5 +428,5 @@ lastmod = ["lastmod" ,":fileModTime", ":default"]

}

return loadLanguageSettings(v, nil)
return nil
}
Loading

0 comments on commit a22b1a7

Please sign in to comment.