mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
hugolib: Read default output formats from site config
This commit is contained in:
parent
4aaed87dd9
commit
dbb83f925a
10 changed files with 101 additions and 65 deletions
|
@ -177,7 +177,7 @@ func (h *HugoSites) assemble(config *BuildCfg) error {
|
|||
for _, p := range s.Pages {
|
||||
// May have been set in front matter
|
||||
if len(p.outputFormats) == 0 {
|
||||
p.outputFormats = s.defaultOutputDefinitions.ForKind(p.Kind)
|
||||
p.outputFormats = s.outputFormats[p.Kind]
|
||||
}
|
||||
if err := p.initTargetPathDescriptor(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -859,7 +859,7 @@ func (p *Page) RelPermalink() string {
|
|||
func (p *Page) initURLs() error {
|
||||
// TODO(bep) output
|
||||
if len(p.outputFormats) == 0 {
|
||||
p.outputFormats = p.s.defaultOutputDefinitions.ForKind(p.Kind)
|
||||
p.outputFormats = p.s.outputFormats[p.Kind]
|
||||
}
|
||||
rel := p.createRelativePermalink()
|
||||
p.permalink = p.s.permalink(rel)
|
||||
|
|
|
@ -45,7 +45,6 @@ func (p *PageOutput) targetPath(addends ...string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
return tp, nil
|
||||
|
||||
}
|
||||
|
||||
func newPageOutput(p *Page, createCopy bool, f output.Format) (*PageOutput, error) {
|
||||
|
|
|
@ -108,7 +108,10 @@ type Site struct {
|
|||
|
||||
disabledKinds map[string]bool
|
||||
|
||||
defaultOutputDefinitions siteOutputDefinitions
|
||||
// Output formats defined in site config per Page Kind, or some defaults
|
||||
// if not set.
|
||||
// Output formats defined in Page front matter will override these.
|
||||
outputFormats map[string]output.Formats
|
||||
|
||||
// Logger etc.
|
||||
*deps.Deps `json:"-"`
|
||||
|
@ -124,12 +127,12 @@ func (s *Site) isEnabled(kind string) bool {
|
|||
// reset returns a new Site prepared for rebuild.
|
||||
func (s *Site) reset() *Site {
|
||||
return &Site{Deps: s.Deps,
|
||||
layoutHandler: output.NewLayoutHandler(s.PathSpec.ThemeSet()),
|
||||
disabledKinds: s.disabledKinds,
|
||||
defaultOutputDefinitions: s.defaultOutputDefinitions,
|
||||
Language: s.Language,
|
||||
owner: s.owner,
|
||||
PageCollections: newPageCollections()}
|
||||
layoutHandler: output.NewLayoutHandler(s.PathSpec.ThemeSet()),
|
||||
disabledKinds: s.disabledKinds,
|
||||
outputFormats: s.outputFormats,
|
||||
Language: s.Language,
|
||||
owner: s.owner,
|
||||
PageCollections: newPageCollections()}
|
||||
}
|
||||
|
||||
// newSite creates a new site with the given configuration.
|
||||
|
@ -145,14 +148,18 @@ func newSite(cfg deps.DepsCfg) (*Site, error) {
|
|||
disabledKinds[disabled] = true
|
||||
}
|
||||
|
||||
outputDefs := createSiteOutputDefinitions(cfg.Cfg)
|
||||
outputFormats, err := createSiteOutputFormats(cfg.Language)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &Site{
|
||||
PageCollections: c,
|
||||
layoutHandler: output.NewLayoutHandler(cfg.Cfg.GetString("themesDir") != ""),
|
||||
Language: cfg.Language,
|
||||
disabledKinds: disabledKinds,
|
||||
defaultOutputDefinitions: outputDefs,
|
||||
PageCollections: c,
|
||||
layoutHandler: output.NewLayoutHandler(cfg.Cfg.GetString("themesDir") != ""),
|
||||
Language: cfg.Language,
|
||||
disabledKinds: disabledKinds,
|
||||
outputFormats: outputFormats,
|
||||
}
|
||||
|
||||
s.Info = newSiteInfo(siteBuilderCfg{s: s, pageCollections: c, language: s.Language})
|
||||
|
@ -2007,7 +2014,7 @@ func (s *Site) newNodePage(typ string, sections ...string) *Page {
|
|||
sections: sections,
|
||||
s: s}
|
||||
|
||||
p.outputFormats = p.s.defaultOutputDefinitions.ForKind(typ)
|
||||
p.outputFormats = p.s.outputFormats[p.Kind]
|
||||
|
||||
return p
|
||||
|
||||
|
|
|
@ -14,56 +14,81 @@
|
|||
package hugolib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/hugo/config"
|
||||
"github.com/spf13/hugo/output"
|
||||
)
|
||||
|
||||
type siteOutputDefinitions []siteOutputDefinition
|
||||
func createSiteOutputFormats(cfg config.Provider) (map[string]output.Formats, error) {
|
||||
if !cfg.IsSet("outputs") {
|
||||
return createDefaultOutputFormats(cfg)
|
||||
}
|
||||
|
||||
type siteOutputDefinition struct {
|
||||
// What Kinds of pages are excluded in this definition.
|
||||
// A blank strings means NONE.
|
||||
// Comma separated list (for now).
|
||||
ExcludedKinds string
|
||||
outFormats := make(map[string]output.Formats)
|
||||
|
||||
Outputs []output.Format
|
||||
}
|
||||
outputs := cfg.GetStringMap("outputs")
|
||||
|
||||
func (defs siteOutputDefinitions) ForKind(kind string) []output.Format {
|
||||
var result []output.Format
|
||||
if outputs == nil || len(outputs) == 0 {
|
||||
// TODO(bep) outputs log a warning?
|
||||
return outFormats, nil
|
||||
}
|
||||
|
||||
for _, def := range defs {
|
||||
if def.ExcludedKinds == "" || !strings.Contains(def.ExcludedKinds, kind) {
|
||||
result = append(result, def.Outputs...)
|
||||
for k, v := range outputs {
|
||||
var formats output.Formats
|
||||
vals := cast.ToStringSlice(v)
|
||||
for _, format := range vals {
|
||||
f, found := output.GetFormat(format)
|
||||
if !found {
|
||||
return nil, fmt.Errorf("Failed to resolve output format %q from site config", format)
|
||||
}
|
||||
formats = append(formats, f)
|
||||
}
|
||||
|
||||
if len(formats) > 0 {
|
||||
outFormats[k] = formats
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func createSiteOutputDefinitions(cfg config.Provider) siteOutputDefinitions {
|
||||
|
||||
var defs siteOutputDefinitions
|
||||
|
||||
// All have HTML
|
||||
defs = append(defs, siteOutputDefinition{ExcludedKinds: "", Outputs: []output.Format{output.HTMLType}})
|
||||
|
||||
// TODO(bep) output deprecate rssURI
|
||||
rssBase := cfg.GetString("rssURI")
|
||||
if rssBase == "" {
|
||||
rssBase = "index"
|
||||
// Make sure every kind has at least one output format
|
||||
for _, kind := range allKinds {
|
||||
if _, found := outFormats[kind]; !found {
|
||||
outFormats[kind] = output.Formats{output.HTMLType}
|
||||
}
|
||||
}
|
||||
|
||||
// RSS has now a well defined media type, so strip any suffix provided
|
||||
rssBase = strings.TrimSuffix(rssBase, path.Ext(rssBase))
|
||||
rssType := output.RSSType
|
||||
rssType.BaseName = rssBase
|
||||
return outFormats, nil
|
||||
|
||||
// Some have RSS
|
||||
defs = append(defs, siteOutputDefinition{ExcludedKinds: "page", Outputs: []output.Format{rssType}})
|
||||
|
||||
return defs
|
||||
}
|
||||
|
||||
func createDefaultOutputFormats(cfg config.Provider) (map[string]output.Formats, error) {
|
||||
outFormats := make(map[string]output.Formats)
|
||||
for _, kind := range allKinds {
|
||||
var formats output.Formats
|
||||
// All have HTML
|
||||
formats = append(formats, output.HTMLType)
|
||||
|
||||
// All but page have RSS
|
||||
if kind != KindPage {
|
||||
// TODO(bep) output deprecate rssURI
|
||||
rssBase := cfg.GetString("rssURI")
|
||||
if rssBase == "" {
|
||||
rssBase = "index"
|
||||
}
|
||||
|
||||
// RSS has now a well defined media type, so strip any suffix provided
|
||||
rssBase = strings.TrimSuffix(rssBase, path.Ext(rssBase))
|
||||
rssType := output.RSSType
|
||||
rssType.BaseName = rssBase
|
||||
formats = append(formats, rssType)
|
||||
|
||||
}
|
||||
|
||||
outFormats[kind] = formats
|
||||
}
|
||||
|
||||
return outFormats, nil
|
||||
}
|
||||
|
|
|
@ -27,23 +27,25 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func TestDefaultOutputDefinitions(t *testing.T) {
|
||||
func TestDefaultOutputFormats(t *testing.T) {
|
||||
t.Parallel()
|
||||
defs := createSiteOutputDefinitions(viper.New())
|
||||
defs, err := createDefaultOutputFormats(viper.New())
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
kind string
|
||||
want []output.Format
|
||||
want output.Formats
|
||||
}{
|
||||
{"RSS not for regular pages", KindPage, []output.Format{output.HTMLType}},
|
||||
{"Home Sweet Home", KindHome, []output.Format{output.HTMLType, output.RSSType}},
|
||||
{"RSS not for regular pages", KindPage, output.Formats{output.HTMLType}},
|
||||
{"Home Sweet Home", KindHome, output.Formats{output.HTMLType, output.RSSType}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := defs.ForKind(tt.kind); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("siteOutputDefinitions.ForKind(%v) = %v, want %v", tt.kind, got, tt.want)
|
||||
if got := defs[tt.kind]; !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("createDefaultOutputFormats(%v) = %v, want %v", tt.kind, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -57,6 +59,7 @@ func TestSiteWithPageOutputs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(bep) output add test for site outputs config
|
||||
func doTestSiteWithPageOutputs(t *testing.T, outputs []string) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -24,14 +24,14 @@ func TestDefaultTypes(t *testing.T) {
|
|||
require.Equal(t, "html", HTMLType.SubType)
|
||||
require.Equal(t, "html", HTMLType.Suffix)
|
||||
|
||||
require.Equal(t, "text/html", HTMLType.MainType())
|
||||
require.Equal(t, "text/html", HTMLType.Type())
|
||||
require.Equal(t, "text/html+html", HTMLType.String())
|
||||
|
||||
require.Equal(t, "application", RSSType.MainType)
|
||||
require.Equal(t, "rss", RSSType.SubType)
|
||||
require.Equal(t, "xml", RSSType.Suffix)
|
||||
|
||||
require.Equal(t, "application/rss", RSSType.MainType())
|
||||
require.Equal(t, "application/rss", RSSType.Type())
|
||||
require.Equal(t, "application/rss+xml", RSSType.String())
|
||||
|
||||
}
|
||||
|
|
|
@ -56,11 +56,11 @@ type TemplateLookupDescriptor struct {
|
|||
ContainsAny func(filename string, subslices [][]byte) (bool, error)
|
||||
}
|
||||
|
||||
func CreateTemplateID(d TemplateLookupDescriptor) (TemplateNames, error) {
|
||||
func CreateTemplateNames(d TemplateLookupDescriptor) (TemplateNames, error) {
|
||||
|
||||
var id TemplateNames
|
||||
|
||||
name := filepath.FromSlash(d.RelPath)
|
||||
name := filepath.ToSlash(d.RelPath)
|
||||
|
||||
if d.Prefix != "" {
|
||||
name = strings.Trim(d.Prefix, "/") + "/" + name
|
||||
|
|
|
@ -124,6 +124,8 @@ func TestLayoutBase(t *testing.T) {
|
|||
} {
|
||||
t.Run(this.name, func(t *testing.T) {
|
||||
|
||||
this.basePathMatchStrings = filepath.FromSlash(this.basePathMatchStrings)
|
||||
|
||||
fileExists := func(filename string) (bool, error) {
|
||||
stringsToMatch := strings.Split(this.basePathMatchStrings, "|")
|
||||
for _, s := range stringsToMatch {
|
||||
|
@ -148,7 +150,7 @@ func TestLayoutBase(t *testing.T) {
|
|||
this.expect.MasterFilename = filepath.FromSlash(this.expect.MasterFilename)
|
||||
this.expect.OverlayFilename = filepath.FromSlash(this.expect.OverlayFilename)
|
||||
|
||||
id, err := CreateTemplateID(this.d)
|
||||
id, err := CreateTemplateNames(this.d)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, this.expect, id, this.name)
|
||||
|
|
|
@ -508,7 +508,7 @@ func (t *GoHTMLTemplate) loadTemplates(absPath string, prefix string) {
|
|||
},
|
||||
}
|
||||
|
||||
tplID, err := output.CreateTemplateID(descriptor)
|
||||
tplID, err := output.CreateTemplateNames(descriptor)
|
||||
if err != nil {
|
||||
t.Log.ERROR.Printf("Failed to resolve template in path %q: %s", path, err)
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue