Skip to content

Commit

Permalink
Allow partial redefinition of the ouputs config
Browse files Browse the repository at this point in the history
Fixes #4487
  • Loading branch information
bep committed Mar 10, 2018
1 parent ae3fa34 commit f8dc47e
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 88 deletions.
86 changes: 47 additions & 39 deletions hugolib/site_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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
}
129 changes: 80 additions & 49 deletions hugolib/site_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
package hugolib

import (
"reflect"
"strings"
"testing"

Expand All @@ -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) {
Expand Down Expand Up @@ -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])
}
10 changes: 10 additions & 0 deletions output/outputFormat.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -149,7 +157,9 @@ var DefaultFormats = Formats{
CSVFormat,
HTMLFormat,
JSONFormat,
RobotsTxtFormat,
RSSFormat,
SitemapFormat,
}

func init() {
Expand Down

0 comments on commit f8dc47e

Please sign in to comment.