Watching: s.Conf.Watching(),
HandlePage: func(pt *pagesfromdata.PagesFromTemplate, pc *pagemeta.PageConfig) error {
s := pt.Site.(*Site)
- if err := pc.Compile(pt.GoTmplFi.Meta().PathInfo.Base(), true, "", s.Log, s.conf.MediaTypes.Config); err != nil {
+ if err := pc.Compile(pt.GoTmplFi.Meta().PathInfo.Base(), true, "", s.Log, s.conf.OutputFormats.Config, s.conf.MediaTypes.Config); err != nil {
return err
}
resource.Staler
*pageMetaParams
- pageMetaFrontMatter
// Set for standalone pages, e.g. robotsTXT.
standaloneOutputFormat output.Format
Path: m.pageConfig.Path,
Params: params,
}
- m.pageMetaFrontMatter = pageMetaFrontMatter{}
}
type pageMetaParams struct {
cascadeOriginal *maps.Ordered[page.PageMatcher, maps.Params] // contains the original cascade as defined in the front matter.
}
-// From page front matter.
-type pageMetaFrontMatter struct {
- configuredOutputFormats output.Formats // outputs defined in front matter.
-}
-
func (m *pageMetaParams) init(preserveOriginal bool) {
if preserveOriginal {
m.paramsOriginal = xmaps.Clone[maps.Params](m.pageConfig.Params)
for i, s := range o {
o[i] = strings.ToLower(s)
}
- if len(o) > 0 {
- // Output formats are explicitly set in front matter, use those.
- outFormats, err := p.s.conf.OutputFormats.Config.GetByNames(o...)
- if err != nil {
- p.s.Log.Errorf("Failed to resolve output formats: %s", err)
- } else {
- pm.configuredOutputFormats = outFormats
- params[loki] = outFormats
- }
- }
+ pm.pageConfig.Outputs = o
case "draft":
draft = new(bool)
*draft = cast.ToBool(v)
return err
}
- if err := pcfg.Compile("", false, ext, p.s.Log, p.s.conf.MediaTypes.Config); err != nil {
+ if err := pcfg.Compile("", false, ext, p.s.Log, p.s.conf.OutputFormats.Config, p.s.conf.MediaTypes.Config); err != nil {
return err
}
// The output formats this page will be rendered to.
func (m *pageMeta) outputFormats() output.Formats {
- if len(m.configuredOutputFormats) > 0 {
- return m.configuredOutputFormats
+ if len(m.pageConfig.ConfiguredOutputFormats) > 0 {
+ return m.pageConfig.ConfiguredOutputFormats
}
return m.s.conf.C.KindOutputFormats[m.Kind()]
}
b.AssertFileContent("public/tags/index.html", "Terms: mytag: 1|§s")
}
+
+func TestContentAdapterOutputsIssue13689(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- hugo.toml --
+disableKinds = ['home','rss','section','sitemap','taxonomy','term']
+[outputs]
+page = ['html','json']
+-- layouts/page.html --
+html: {{ .Title }}
+-- layouts/page.json --
+json: {{ .Title }}
+-- content/p1.md --
+---
+title: p1
+---
+-- content/p2.md --
+---
+title: p2
+outputs:
+ - html
+---
+-- content/_content.gotmpl --
+{{ $page := dict "path" "p3" "title" "p3" }}
+{{ $.AddPage $page }}
+
+{{ $page := dict "path" "p4" "title" "p4" "outputs" (slice "html") }}
+{{ $.AddPage $page }}
+`
+
+ b := hugolib.Test(t, files)
+
+ b.AssertFileExists("public/p1/index.html", true)
+ b.AssertFileExists("public/p1/index.json", true)
+ b.AssertFileExists("public/p2/index.html", true)
+ b.AssertFileExists("public/p2/index.json", false)
+ b.AssertFileExists("public/p3/index.html", true)
+ b.AssertFileExists("public/p3/index.json", true)
+ b.AssertFileExists("public/p4/index.html", true)
+ b.AssertFileExists("public/p4/index.json", false) // currently returns true
+}
Tree: s.pageMap.treePages,
Handle: func(key string, n contentNodeI, match doctree.DimensionFlag) (bool, error) {
if p, ok := n.(*pageState); ok {
- for _, f := range p.m.configuredOutputFormats {
+ for _, f := range p.m.pageConfig.ConfiguredOutputFormats {
if !formatSet[f.Name] {
formats = append(formats, f)
formatSet[f.Name] = true
"github.com/gohugoio/hugo/hugofs/files"
"github.com/gohugoio/hugo/markup"
"github.com/gohugoio/hugo/media"
+ "github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources/kinds"
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/resources/resource"
Content Source
// Compiled values.
- CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"`
- ContentMediaType media.Type `mapstructure:"-" json:"-"`
- IsFromContentAdapter bool `mapstructure:"-" json:"-"`
+ CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"`
+ ContentMediaType media.Type `mapstructure:"-" json:"-"`
+ ConfiguredOutputFormats output.Formats `mapstructure:"-" json:"-"`
+ IsFromContentAdapter bool `mapstructure:"-" json:"-"`
}
var DefaultPageConfig = PageConfig{
}
// Compile sets up the page configuration after all fields have been set.
-func (p *PageConfig) Compile(basePath string, pagesFromData bool, ext string, logger loggers.Logger, mediaTypes media.Types) error {
+func (p *PageConfig) Compile(basePath string, pagesFromData bool, ext string, logger loggers.Logger, outputFormats output.Formats, mediaTypes media.Types) error {
// In content adapters, we always get relative paths.
if basePath != "" {
p.Path = path.Join(basePath, p.Path)
p.Content.Markup = p.ContentMediaType.SubType
}
+ if len(p.Outputs) > 0 {
+ outFormats, err := outputFormats.GetByNames(p.Outputs...)
+ if err != nil {
+ return fmt.Errorf("failed to resolve output formats %v: %w", p.Outputs, err)
+ } else {
+ p.ConfiguredOutputFormats = outFormats
+ }
+ }
+
if pagesFromData {
if p.Kind == "" {
p.Kind = kinds.KindPage
// but also because people tend to use use the filename to name their resources (with spaces and all),
// and this isn't relevant when creating resources from an API where it's easy to add textual meta data.
p.Path = paths.NormalizePathStringBasic(p.Path)
+
}
if p.Cascade != nil {
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/testconfig"
"github.com/gohugoio/hugo/media"
+ "github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources/page/pagemeta"
} {
var pc pagemeta.PageConfig
pc.Content.Markup = test.in
- c.Assert(pc.Compile("", true, "", logger, media.DefaultTypes), qt.IsNil)
+ c.Assert(pc.Compile("", true, "", logger, output.DefaultFormats, media.DefaultTypes), qt.IsNil)
c.Assert(pc.ContentMediaType.Type, qt.Equals, test.expected)
}
}