aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2018-03-10 11:45:29 +0100
committerBjørn Erik Pedersen <[email protected]>2018-03-10 16:57:25 +0100
commitf8dc47eeffa847fd0b51e376da355e3d957848a6 (patch)
treefd661968ce136ee69159a3560310b65dc8a17fb6
parentae3fa349de6daf1bbcd09ffc859d6b2e44764795 (diff)
downloadhugo-f8dc47eeffa847fd0b51e376da355e3d957848a6.tar.gz
hugo-f8dc47eeffa847fd0b51e376da355e3d957848a6.zip
Allow partial redefinition of the ouputs config
Fixes #4487
-rw-r--r--hugolib/site_output.go86
-rw-r--r--hugolib/site_output_test.go129
-rw-r--r--output/outputFormat.go10
3 files changed, 137 insertions, 88 deletions
diff --git a/hugolib/site_output.go b/hugolib/site_output.go
index 5a99692a3..497092e8c 100644
--- a/hugolib/site_output.go
+++ b/hugolib/site_output.go
@@ -24,9 +24,46 @@ import (
"github.com/spf13/cast"
)
+func createDefaultOutputFormats(allFormats output.Formats, cfg config.Provider) map[string]output.Formats {
+ rssOut, _ := allFormats.GetByName(output.RSSFormat.Name)
+ htmlOut, _ := allFormats.GetByName(output.HTMLFormat.Name)
+ robotsOut, _ := allFormats.GetByName(output.RobotsTxtFormat.Name)
+ sitemapOut, _ := allFormats.GetByName(output.SitemapFormat.Name)
+
+ // TODO(bep) this mumbo jumbo is deprecated and should be removed, but there are tests that
+ // depends on this, so that will have to wait.
+ rssBase := cfg.GetString("rssURI")
+ if rssBase == "" || rssBase == "index.xml" {
+ rssBase = rssOut.BaseName
+ } else {
+ // Remove in Hugo 0.36.
+ helpers.Deprecated("Site config", "rssURI", "Set baseName in outputFormats.RSS", true)
+ // RSS has now a well defined media type, so strip any suffix provided
+ rssBase = strings.TrimSuffix(rssBase, path.Ext(rssBase))
+ }
+
+ rssOut.BaseName = rssBase
+
+ return map[string]output.Formats{
+ KindPage: output.Formats{htmlOut},
+ KindHome: output.Formats{htmlOut, rssOut},
+ KindSection: output.Formats{htmlOut, rssOut},
+ KindTaxonomy: output.Formats{htmlOut, rssOut},
+ KindTaxonomyTerm: output.Formats{htmlOut, rssOut},
+ // Below are for conistency. They are currently not used during rendering.
+ kindRSS: output.Formats{rssOut},
+ kindSitemap: output.Formats{sitemapOut},
+ kindRobotsTXT: output.Formats{robotsOut},
+ kind404: output.Formats{htmlOut},
+ }
+
+}
+
func createSiteOutputFormats(allFormats output.Formats, cfg config.Provider) (map[string]output.Formats, error) {
+ defaultOutputFormats := createDefaultOutputFormats(allFormats, cfg)
+
if !cfg.IsSet("outputs") {
- return createDefaultOutputFormats(allFormats, cfg)
+ return defaultOutputFormats, nil
}
outFormats := make(map[string]output.Formats)
@@ -37,6 +74,8 @@ func createSiteOutputFormats(allFormats output.Formats, cfg config.Provider) (ma
return outFormats, nil
}
+ seen := make(map[string]bool)
+
for k, v := range outputs {
var formats output.Formats
vals := cast.ToStringSlice(v)
@@ -48,52 +87,21 @@ func createSiteOutputFormats(allFormats output.Formats, cfg config.Provider) (ma
formats = append(formats, f)
}
+ // This effectively prevents empty outputs entries for a given Kind.
+ // We need at least one.
if len(formats) > 0 {
+ seen[k] = true
outFormats[k] = formats
}
}
- // Make sure every kind has at least one output format
- for _, kind := range allKinds {
- if _, found := outFormats[kind]; !found {
- outFormats[kind] = output.Formats{output.HTMLFormat}
+ // Add defaults for the entries not provided by the user.
+ for k, v := range defaultOutputFormats {
+ if !seen[k] {
+ outFormats[k] = v
}
}
return outFormats, nil
}
-
-func createDefaultOutputFormats(allFormats output.Formats, cfg config.Provider) (map[string]output.Formats, error) {
- outFormats := make(map[string]output.Formats)
- rssOut, _ := allFormats.GetByName(output.RSSFormat.Name)
- htmlOut, _ := allFormats.GetByName(output.HTMLFormat.Name)
-
- for _, kind := range allKinds {
- var formats output.Formats
- // All have HTML
- formats = append(formats, htmlOut)
-
- // All but page have RSS
- if kind != KindPage {
-
- rssBase := cfg.GetString("rssURI")
- if rssBase == "" || rssBase == "index.xml" {
- rssBase = rssOut.BaseName
- } else {
- // Remove in Hugo 0.36.
- helpers.Deprecated("Site config", "rssURI", "Set baseName in outputFormats.RSS", true)
- // RSS has now a well defined media type, so strip any suffix provided
- rssBase = strings.TrimSuffix(rssBase, path.Ext(rssBase))
- }
-
- rssOut.BaseName = rssBase
- formats = append(formats, rssOut)
-
- }
-
- outFormats[kind] = formats
- }
-
- return outFormats, nil
-}
diff --git a/hugolib/site_output_test.go b/hugolib/site_output_test.go
index a8a43d625..7da6f105f 100644
--- a/hugolib/site_output_test.go
+++ b/hugolib/site_output_test.go
@@ -14,7 +14,6 @@
package hugolib
import (
- "reflect"
"strings"
"testing"
@@ -29,54 +28,6 @@ import (
"github.com/spf13/viper"
)
-func TestDefaultOutputFormats(t *testing.T) {
- t.Parallel()
- defs, err := createDefaultOutputFormats(output.DefaultFormats, viper.New())
-
- require.NoError(t, err)
-
- tests := []struct {
- name string
- kind string
- want output.Formats
- }{
- {"RSS not for regular pages", KindPage, output.Formats{output.HTMLFormat}},
- {"Home Sweet Home", KindHome, output.Formats{output.HTMLFormat, output.RSSFormat}},
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- if got := defs[tt.kind]; !reflect.DeepEqual(got, tt.want) {
- t.Errorf("createDefaultOutputFormats(%v) = %v, want %v", tt.kind, got, tt.want)
- }
- })
- }
-}
-
-func TestDefaultOutputFormatsWithOverrides(t *testing.T) {
- t.Parallel()
-
- htmlOut := output.HTMLFormat
- htmlOut.BaseName = "htmlindex"
- rssOut := output.RSSFormat
- rssOut.BaseName = "feed"
-
- defs, err := createDefaultOutputFormats(output.Formats{htmlOut, rssOut}, viper.New())
-
- homeDefs := defs[KindHome]
-
- rss, found := homeDefs.GetByName("RSS")
- require.True(t, found)
- require.Equal(t, rss.BaseName, "feed")
-
- html, found := homeDefs.GetByName("HTML")
- require.True(t, found)
- require.Equal(t, html.BaseName, "htmlindex")
-
- require.NoError(t, err)
-
-}
-
func TestSiteWithPageOutputs(t *testing.T) {
for _, outputs := range [][]string{{"html", "json", "calendar"}, {"json"}} {
t.Run(fmt.Sprintf("%v", outputs), func(t *testing.T) {
@@ -373,3 +324,83 @@ baseName = "customdelimbase"
require.Equal(t, "/blog/customdelimbase_del", outputs.Get("CUS").RelPermalink())
}
+
+func TestCreateSiteOutputFormats(t *testing.T) {
+ assert := require.New(t)
+
+ outputsConfig := map[string]interface{}{
+ KindHome: []string{"HTML", "JSON"},
+ KindSection: []string{"JSON"},
+ }
+
+ cfg := viper.New()
+ cfg.Set("outputs", outputsConfig)
+
+ outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg)
+ assert.NoError(err)
+ assert.Equal(output.Formats{output.JSONFormat}, outputs[KindSection])
+ assert.Equal(output.Formats{output.HTMLFormat, output.JSONFormat}, outputs[KindHome])
+
+ // Defaults
+ assert.Equal(output.Formats{output.HTMLFormat, output.RSSFormat}, outputs[KindTaxonomy])
+ assert.Equal(output.Formats{output.HTMLFormat, output.RSSFormat}, outputs[KindTaxonomyTerm])
+ assert.Equal(output.Formats{output.HTMLFormat}, outputs[KindPage])
+
+ // These aren't (currently) in use when rendering in Hugo,
+ // but the pages needs to be assigned an output format,
+ // so these should also be correct/sensible.
+ assert.Equal(output.Formats{output.RSSFormat}, outputs[kindRSS])
+ assert.Equal(output.Formats{output.SitemapFormat}, outputs[kindSitemap])
+ assert.Equal(output.Formats{output.RobotsTxtFormat}, outputs[kindRobotsTXT])
+ assert.Equal(output.Formats{output.HTMLFormat}, outputs[kind404])
+
+}
+
+func TestCreateSiteOutputFormatsInvalidConfig(t *testing.T) {
+ assert := require.New(t)
+
+ outputsConfig := map[string]interface{}{
+ KindHome: []string{"FOO", "JSON"},
+ }
+
+ cfg := viper.New()
+ cfg.Set("outputs", outputsConfig)
+
+ _, err := createSiteOutputFormats(output.DefaultFormats, cfg)
+ assert.Error(err)
+}
+
+func TestCreateSiteOutputFormatsEmptyConfig(t *testing.T) {
+ assert := require.New(t)
+
+ outputsConfig := map[string]interface{}{
+ KindHome: []string{},
+ }
+
+ cfg := viper.New()
+ cfg.Set("outputs", outputsConfig)
+
+ outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg)
+ assert.NoError(err)
+ assert.Equal(output.Formats{output.HTMLFormat, output.RSSFormat}, outputs[KindHome])
+}
+
+func TestCreateSiteOutputFormatsCustomFormats(t *testing.T) {
+ assert := require.New(t)
+
+ outputsConfig := map[string]interface{}{
+ KindHome: []string{},
+ }
+
+ cfg := viper.New()
+ cfg.Set("outputs", outputsConfig)
+
+ var (
+ customRSS = output.Format{Name: "RSS", BaseName: "customRSS"}
+ customHTML = output.Format{Name: "HTML", BaseName: "customHTML"}
+ )
+
+ outputs, err := createSiteOutputFormats(output.Formats{customRSS, customHTML}, cfg)
+ assert.NoError(err)
+ assert.Equal(output.Formats{customHTML, customRSS}, outputs[KindHome])
+}
diff --git a/output/outputFormat.go b/output/outputFormat.go
index 0920e5736..877850160 100644
--- a/output/outputFormat.go
+++ b/output/outputFormat.go
@@ -140,6 +140,14 @@ var (
NoUgly: true,
Rel: "alternate",
}
+
+ SitemapFormat = Format{
+ Name: "Sitemap",
+ MediaType: media.XMLType,
+ BaseName: "sitemap",
+ NoUgly: true,
+ Rel: "sitemap",
+ }
)
var DefaultFormats = Formats{
@@ -149,7 +157,9 @@ var DefaultFormats = Formats{
CSVFormat,
HTMLFormat,
JSONFormat,
+ RobotsTxtFormat,
RSSFormat,
+ SitemapFormat,
}
func init() {