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 18, 2018
1 parent 3cc3b2c commit b643631
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 6 deletions.
76 changes: 75 additions & 1 deletion 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 Down Expand Up @@ -85,7 +86,8 @@ func LoadConfig(d ConfigSourceDescriptor) (*viper.Viper, error) {
return v, err
}

return v, nil
return v, loadThemeConfig(fs, v)

}

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

func loadThemeConfig(fs afero.Fs, v1 *viper.Viper) error {

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

themesDir := v1.GetString("themesDir")
configDir := filepath.Join(themesDir, theme)

var configPath string
var exists bool
var err error

for _, exensionsToCheck := range []string{"toml", "yaml", "yml", "json"} {
configPath = filepath.Join(configDir, "config."+exensionsToCheck)
exists, err = helpers.Exists(configPath, fs)
if err != nil {
return err
}
if exists {
break
}
}

if !exists {
return nil
}

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

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

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

return nil

}

func mergeStringMapKeepLeft(key string, v1, v2 *viper.Viper) {
if !v1.IsSet(key) {
if v2.IsSet(key) {
v1.Set(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 @@ -282,4 +355,5 @@ lastmod = ["lastmod" ,":fileModTime", ":default"]
}

return loadLanguageSettings(v, nil)

}
93 changes: 88 additions & 5 deletions hugolib/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@
package hugolib

import (
"fmt"
"testing"

"github.com/spf13/viper"

"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestLoadConfig(t *testing.T) {
t.Parallel()

assert := require.New(t)

// Add a random config variable for testing.
// side = page in Norwegian.
configContent := `
Expand All @@ -37,13 +41,16 @@ func TestLoadConfig(t *testing.T) {
cfg, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Name: "hugo.toml"})
require.NoError(t, err)

assert.Equal(t, "side", cfg.GetString("paginatePath"))
assert.Equal("side", cfg.GetString("paginatePath"))
// default
assert.Equal(t, "layouts", cfg.GetString("layoutDir"))
assert.Equal("layouts", cfg.GetString("layoutDir"))
}

func TestLoadMultiConfig(t *testing.T) {
t.Parallel()

assert := require.New(t)

// Add a random config variable for testing.
// side = page in Norwegian.
configContentBase := `
Expand All @@ -62,6 +69,82 @@ func TestLoadMultiConfig(t *testing.T) {
cfg, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Name: "base.toml,override.toml"})
require.NoError(t, err)

assert.Equal(t, "top", cfg.GetString("paginatePath"))
assert.Equal(t, "same", cfg.GetString("DontChange"))
assert.Equal("top", cfg.GetString("paginatePath"))
assert.Equal("same", cfg.GetString("DontChange"))
}

func TestLoadConfigFromTheme(t *testing.T) {
t.Parallel()

assert := require.New(t)

mainConfig := `
theme = "test-theme"
baseURL = "https://example.com/"
[frontmatter]
date = ["date","publishDate"]
[params]
p1 = "p1 main"
p2 = "p2 main"
[mediaTypes]
[mediaTypes."text/m1"]
suffix = "m1main"
[outputFormats.o1]
mediaType = "text/m1"
baseName = "o1main"
`

themeConfig := `
baseURL = "http://bep.is/"
# Can not be set in theme.
[frontmatter]
expiryDate = ["date"]
[params]
p1 = "p1 theme"
p2 = "p2 theme"
p3 = "p3 theme"
[mediaTypes]
[mediaTypes."text/m1"]
suffix = "m1theme"
[mediaTypes."text/m2"]
suffix = "m2theme"
[outputFormats.o1]
mediaType = "text/m1"
baseName = "o1theme"
[outputFormats.o2]
mediaType = "text/m1"
baseName = "o2theme"
`

b := newTestSitesBuilder(t)
b.WithConfigFile("toml", mainConfig).WithThemeConfigFile("toml", themeConfig)
b.CreateSites().Build(BuildCfg{})

expected := map[string]interface{}{
"baseurl": "http://bep.is/",
"frontmatter": map[string]interface{}{
"date": []interface{}{"date", "publishDate"},
},
"params": map[string]interface{}{
"p1": "p1 main",
"p2": "p2 main",
"p3": "p3 theme",
},
}

got := b.Cfg.(*viper.Viper).AllSettings()

assert.Equal(expected["params"], got["params"])
assert.Equal(expected["frontmatter"], got["frontmatter"])

fmt.Println(">", expected, "\ngot", got)

}
2 changes: 2 additions & 0 deletions hugolib/site.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ func NewSite(cfg deps.DepsCfg) (*Site, error) {
// NewSiteDefaultLang creates a new site in the default language.
// The site will have a template system loaded and ready to use.
// Note: This is mainly used in single site tests.
// TODO(bep) test refactor -- remove
func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
v := viper.New()
if err := loadDefaultSettingsFor(v); err != nil {
Expand All @@ -307,6 +308,7 @@ func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (
// NewEnglishSite creates a new site in English language.
// The site will have a template system loaded and ready to use.
// Note: This is mainly used in single site tests.
// TODO(bep) test refactor -- remove
func NewEnglishSite(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
v := viper.New()
if err := loadDefaultSettingsFor(v); err != nil {
Expand Down
11 changes: 11 additions & 0 deletions hugolib/testhelpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type sitesBuilder struct {

H *HugoSites

theme string

// Default toml
configFormat string

Expand Down Expand Up @@ -97,6 +99,15 @@ func (s *sitesBuilder) WithConfigFile(format, conf string) *sitesBuilder {
return s
}

func (s *sitesBuilder) WithThemeConfigFile(format, conf string) *sitesBuilder {
if s.theme == "" {
s.theme = "test-theme"
}
filename := filepath.Join("themes", s.theme, "config."+format)
writeSource(s.T, s.Fs, filename, conf)
return s
}

func (s *sitesBuilder) WithSimpleConfigFile() *sitesBuilder {
var config = `
baseURL = "http://example.com/"
Expand Down

0 comments on commit b643631

Please sign in to comment.