mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-29 22:29:56 +02:00
@@ -356,7 +356,7 @@ func (m *pageMap) addPagesFromGoTmplFi(fi hugofs.FileMetaInfo, buildConfig *Buil
|
||||
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.OutputFormats.Config, s.conf.MediaTypes.Config); err != nil {
|
||||
if err := pc.CompileForPagesFromDataPre(pt.GoTmplFi.Meta().PathInfo.Base(), m.s.Log, s.conf.MediaTypes.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -1695,7 +1695,9 @@ func (sa *sitePagesAssembler) assembleTermsAndTranslations() error {
|
||||
pathInfo: pi,
|
||||
pageMetaParams: &pageMetaParams{
|
||||
pageConfig: &pagemeta.PageConfig{
|
||||
Kind: kinds.KindTerm,
|
||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
||||
Kind: kinds.KindTerm,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1956,7 +1958,9 @@ func (sa *sitePagesAssembler) addStandalonePages() error {
|
||||
pathInfo: s.Conf.PathParser().Parse(files.ComponentFolderContent, key+f.MediaType.FirstSuffix.FullSuffix),
|
||||
pageMetaParams: &pageMetaParams{
|
||||
pageConfig: &pagemeta.PageConfig{
|
||||
Kind: kind,
|
||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
||||
Kind: kind,
|
||||
},
|
||||
},
|
||||
},
|
||||
standaloneOutputFormat: f,
|
||||
@@ -2082,7 +2086,9 @@ func (sa *sitePagesAssembler) addMissingRootSections() error {
|
||||
pathInfo: p,
|
||||
pageMetaParams: &pageMetaParams{
|
||||
pageConfig: &pagemeta.PageConfig{
|
||||
Kind: kinds.KindHome,
|
||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
||||
Kind: kinds.KindHome,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -2115,7 +2121,9 @@ func (sa *sitePagesAssembler) addMissingTaxonomies() error {
|
||||
pathInfo: sa.Conf.PathParser().Parse(files.ComponentFolderContent, key+"/_index.md"),
|
||||
pageMetaParams: &pageMetaParams{
|
||||
pageConfig: &pagemeta.PageConfig{
|
||||
Kind: kinds.KindTaxonomy,
|
||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
||||
Kind: kinds.KindTaxonomy,
|
||||
},
|
||||
},
|
||||
},
|
||||
singular: viewName.singular,
|
||||
|
@@ -72,12 +72,7 @@ type pageMeta struct {
|
||||
// Prepare for a rebuild of the data passed in from front matter.
|
||||
func (m *pageMeta) setMetaPostPrepareRebuild() {
|
||||
params := xmaps.Clone(m.paramsOriginal)
|
||||
m.pageMetaParams.pageConfig = &pagemeta.PageConfig{
|
||||
Kind: m.pageConfig.Kind,
|
||||
Lang: m.pageConfig.Lang,
|
||||
Path: m.pageConfig.Path,
|
||||
Params: params,
|
||||
}
|
||||
m.pageMetaParams.pageConfig = pagemeta.ClonePageConfigForRebuild(m.pageMetaParams.pageConfig, params)
|
||||
}
|
||||
|
||||
type pageMetaParams struct {
|
||||
@@ -94,7 +89,11 @@ type pageMetaParams struct {
|
||||
|
||||
func (m *pageMetaParams) init(preserveOriginal bool) {
|
||||
if preserveOriginal {
|
||||
m.paramsOriginal = xmaps.Clone[maps.Params](m.pageConfig.Params)
|
||||
if m.pageConfig.IsFromContentAdapter {
|
||||
m.paramsOriginal = xmaps.Clone(m.pageConfig.ContentAdapterData)
|
||||
} else {
|
||||
m.paramsOriginal = xmaps.Clone(m.pageConfig.Params)
|
||||
}
|
||||
m.cascadeOriginal = m.pageConfig.CascadeCompiled.Clone()
|
||||
}
|
||||
}
|
||||
@@ -254,7 +253,7 @@ func (p *pageMeta) setMetaPre(pi *contentParseInfo, logger loggers.Logger, conf
|
||||
// Check for any cascade define on itself.
|
||||
if cv, found := frontmatter["cascade"]; found {
|
||||
var err error
|
||||
cascade, err := page.DecodeCascade(logger, cv)
|
||||
cascade, err := page.DecodeCascade(logger, true, cv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -341,18 +340,29 @@ func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, maps.Pa
|
||||
}
|
||||
|
||||
// Cascade is also applied to itself.
|
||||
var err error
|
||||
cascade.Range(func(k page.PageMatcher, v maps.Params) bool {
|
||||
if !k.Matches(ps) {
|
||||
return true
|
||||
}
|
||||
for kk, vv := range v {
|
||||
if _, found := ps.m.pageConfig.Params[kk]; !found {
|
||||
ps.m.pageConfig.Params[kk] = vv
|
||||
if ps.m.pageConfig.IsFromContentAdapter {
|
||||
if _, found := ps.m.pageConfig.ContentAdapterData[kk]; !found {
|
||||
ps.m.pageConfig.ContentAdapterData[kk] = vv
|
||||
}
|
||||
} else {
|
||||
if _, found := ps.m.pageConfig.Params[kk]; !found {
|
||||
ps.m.pageConfig.Params[kk] = vv
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ps.setMetaPostParams(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -398,6 +408,12 @@ func (p *pageState) setMetaPostParams() error {
|
||||
PathOrTitle: p.pathOrTitle(),
|
||||
}
|
||||
|
||||
if isContentAdapter {
|
||||
if err := pm.pageConfig.Compile(ext, p.s.Log, p.s.conf.OutputFormats.Config, p.s.conf.MediaTypes.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the date separately
|
||||
// TODO(bep) we need to "do more" in this area so this can be split up and
|
||||
// more easily tested without the Page, but the coupling is strong.
|
||||
@@ -656,7 +672,7 @@ params:
|
||||
return err
|
||||
}
|
||||
|
||||
if err := pcfg.Compile("", false, ext, p.s.Log, p.s.conf.OutputFormats.Config, p.s.conf.MediaTypes.Config); err != nil {
|
||||
if err := pcfg.Compile(ext, p.s.Log, p.s.conf.OutputFormats.Config, p.s.conf.MediaTypes.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -91,17 +91,20 @@ func (p *pagesFromDataTemplateContext) AddPage(v any) (string, error) {
|
||||
|
||||
pd := pagemeta.DefaultPageConfig
|
||||
pd.IsFromContentAdapter = true
|
||||
pd.ContentAdapterData = m
|
||||
|
||||
if err := mapstructure.WeakDecode(m, &pd); err != nil {
|
||||
return "", fmt.Errorf("failed to decode page map: %w", err)
|
||||
// The rest will be handled after the cascade is calculated and applied.
|
||||
if err := mapstructure.WeakDecode(pd.ContentAdapterData, &pd.PageConfigEarly); err != nil {
|
||||
err = fmt.Errorf("failed to decode page map: %w", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
p.p.buildState.NumPagesAdded++
|
||||
|
||||
if err := pd.Validate(true); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
p.p.buildState.NumPagesAdded++
|
||||
|
||||
return "", p.p.HandlePage(p.p, &pd)
|
||||
}
|
||||
|
||||
|
@@ -821,3 +821,97 @@ outputs:
|
||||
b.AssertFileExists("public/p4/index.html", true)
|
||||
b.AssertFileExists("public/p4/index.json", false) // currently returns true
|
||||
}
|
||||
|
||||
func TestContentAdapterOutputsIssue13692(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ['page','home','sitemap','taxonomy','term']
|
||||
[[cascade]]
|
||||
outputs = ['html','json']
|
||||
[cascade.target]
|
||||
path = '{/s2,/s4}'
|
||||
-- layouts/section.html --
|
||||
html: {{ .Title }}
|
||||
-- layouts/section.json --
|
||||
json: {{ .Title }}
|
||||
-- content/s1/_index.md --
|
||||
---
|
||||
title: s1
|
||||
---
|
||||
-- content/s2/_index.md --
|
||||
---
|
||||
title: s2
|
||||
---
|
||||
-- content/_content.gotmpl --
|
||||
{{ $page := dict "path" "s3" "title" "s3" "kind" "section" }}
|
||||
{{ $.AddPage $page }}
|
||||
|
||||
{{ $page := dict "path" "s4" "title" "s4" "kind" "section" }}
|
||||
{{ $.AddPage $page }}
|
||||
|
||||
{{ $page := dict "path" "s5" "title" "s5" "kind" "section" "outputs" (slice "html") }}
|
||||
{{ $.AddPage $page }}
|
||||
`
|
||||
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
b.AssertFileExists("public/s1/index.html", true)
|
||||
b.AssertFileExists("public/s1/index.json", false)
|
||||
b.AssertFileExists("public/s1/index.xml", true)
|
||||
|
||||
b.AssertFileExists("public/s2/index.html", true)
|
||||
b.AssertFileExists("public/s2/index.json", true)
|
||||
b.AssertFileExists("public/s2/index.xml", false)
|
||||
|
||||
b.AssertFileExists("public/s3/index.html", true)
|
||||
b.AssertFileExists("public/s3/index.json", false)
|
||||
b.AssertFileExists("public/s3/index.xml", true)
|
||||
|
||||
b.AssertFileExists("public/s4/index.html", true)
|
||||
b.AssertFileExists("public/s4/index.json", true)
|
||||
b.AssertFileExists("public/s4/index.xml", false)
|
||||
|
||||
b.AssertFileExists("public/s5/index.html", true)
|
||||
b.AssertFileExists("public/s5/index.json", false)
|
||||
b.AssertFileExists("public/s5/index.xml", false)
|
||||
}
|
||||
|
||||
func TestContentAdapterCascadeBasic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableLiveReload = true
|
||||
-- content/_index.md --
|
||||
---
|
||||
cascade:
|
||||
- title: foo
|
||||
target:
|
||||
path: "**"
|
||||
---
|
||||
-- layouts/all.html --
|
||||
Title: {{ .Title }}|Content: {{ .Content }}|
|
||||
-- content/_content.gotmpl --
|
||||
{{ $content := dict
|
||||
"mediaType" "text/markdown"
|
||||
"value" "The _Hunchback of Notre Dame_ was written by Victor Hugo."
|
||||
}}
|
||||
|
||||
{{ $page := dict "path" "s1" "kind" "page" }}
|
||||
{{ $.AddPage $page }}
|
||||
{{ $page := dict "path" "s2" "kind" "page" "title" "bar" "content" $content }}
|
||||
{{ $.AddPage $page }}
|
||||
|
||||
`
|
||||
|
||||
b := hugolib.TestRunning(t, files)
|
||||
|
||||
b.AssertFileContent("public/s1/index.html", "Title: foo|")
|
||||
b.AssertFileContent("public/s2/index.html", "Title: bar|", "Content: <p>The <em>Hunchback of Notre Dame</em> was written by Victor Hugo.</p>")
|
||||
|
||||
b.EditFileReplaceAll("content/_index.md", "foo", "baz").Build()
|
||||
|
||||
b.AssertFileContent("public/s1/index.html", "Title: baz|")
|
||||
}
|
||||
|
Reference in New Issue
Block a user