diff --git a/hugolib/page__content.go b/hugolib/page__content.go index 1ef31f0f986..1119a8a95bb 100644 --- a/hugolib/page__content.go +++ b/hugolib/page__content.go @@ -57,14 +57,14 @@ type pageContentReplacement struct { func (m *pageMeta) parseFrontMatter(h *HugoSites, pid uint64) (*contentParseInfo, error) { var ( - sourceKey string - openSource hugio.OpenReadSeekCloser - hasContent = m.pageConfig.IsFromContentAdapter + sourceKey string + openSource hugio.OpenReadSeekCloser + isFromContentAdapter = m.pageConfig.IsFromContentAdapter ) - if m.f != nil && !hasContent { + if m.f != nil && !isFromContentAdapter { sourceKey = filepath.ToSlash(m.f.Filename()) - if !hasContent { + if !isFromContentAdapter { meta := m.f.FileInfo().Meta() openSource = func() (hugio.ReadSeekCloser, error) { r, err := meta.Open() @@ -74,7 +74,7 @@ func (m *pageMeta) parseFrontMatter(h *HugoSites, pid uint64) (*contentParseInfo return r, nil } } - } else if hasContent { + } else if isFromContentAdapter { openSource = m.pageConfig.Content.ValueAsOpenReadSeekCloser() } @@ -96,7 +96,9 @@ func (m *pageMeta) parseFrontMatter(h *HugoSites, pid uint64) (*contentParseInfo items, err := pageparser.ParseBytes( source, - pageparser.Config{}, + pageparser.Config{ + NoFrontMatter: isFromContentAdapter, + }, ) if err != nil { return nil, err @@ -104,7 +106,7 @@ func (m *pageMeta) parseFrontMatter(h *HugoSites, pid uint64) (*contentParseInfo pi.itemsStep1 = items - if hasContent { + if isFromContentAdapter { // No front matter. return pi, nil } diff --git a/hugolib/page__menus.go b/hugolib/page__menus.go index 5bed2bc033d..1666036ce58 100644 --- a/hugolib/page__menus.go +++ b/hugolib/page__menus.go @@ -62,8 +62,22 @@ func (p *pageMenus) init() { p.p, ) + params := p.p.Params() + + var menus any + var ok bool + + if p.p.m.pageConfig.Menus != nil { + menus = p.p.m.pageConfig.Menus + } else { + menus, ok = params["menus"] + if !ok { + menus = params["menu"] + } + } + var err error - p.pm, err = navigation.PageMenusFromPage(p.p) + p.pm, err = navigation.PageMenusFromPage(menus, p.p) if err != nil { p.p.s.Log.Errorln(p.p.wrapError(err)) } diff --git a/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go b/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go index 7f0f19f1c93..3a37c233b96 100644 --- a/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go +++ b/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go @@ -585,3 +585,56 @@ value: data1 b.AssertLogNotContains("WARN") } + +func TestPagesFromGoTmplShortcodeNoPreceddingCharacterIssue12544(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ['home','rss','section','sitemap','taxonomy','term'] +-- content/_content.gotmpl -- +{{ $content := dict "mediaType" "text/html" "value" "x{{< sc >}}" }} +{{ .AddPage (dict "content" $content "path" "a") }} + +{{ $content := dict "mediaType" "text/html" "value" "{{< sc >}}" }} +{{ .AddPage (dict "content" $content "path" "b") }} +-- layouts/_default/single.html -- +|{{ .Content }}| +-- layouts/shortcodes/sc.html -- +foo +{{- /**/ -}} +` + + b := hugolib.Test(t, files) + + b.AssertFileContent("public/a/index.html", "|xfoo|") + b.AssertFileContent("public/b/index.html", "|foo|") // fails +} + +func TestPagesFromGoTmplMenus(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ['rss','section','sitemap','taxonomy','term'] + +[menus] +[[menus.main]] +name = "Main" +[[menus.footer]] +name = "Footer" +-- content/_content.gotmpl -- +{{ .AddPage (dict "path" "p1" "title" "p1" "menus" "main" ) }} +{{ .AddPage (dict "path" "p2" "title" "p2" "menus" (slice "main" "footer")) }} +-- layouts/index.html -- +Main: {{ range index site.Menus.main }}{{ .Name }}|{{ end }}| +Footer: {{ range index site.Menus.footer }}{{ .Name }}|{{ end }}| + +` + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", + "Main: Main|p1|p2||", + "Footer: Footer|p2||", + ) +} diff --git a/navigation/pagemenus.go b/navigation/pagemenus.go index 3ff49cf8143..e89a366dde0 100644 --- a/navigation/pagemenus.go +++ b/navigation/pagemenus.go @@ -41,20 +41,8 @@ type MenuQueryProvider interface { IsMenuCurrent(menuID string, inme *MenuEntry) bool } -func PageMenusFromPage(p Page) (PageMenus, error) { - params := p.Params() - - ms, ok := params["menus"] - if !ok { - ms, ok = params["menu"] - } - +func PageMenusFromPage(ms any, p Page) (PageMenus, error) { pm := PageMenus{} - - if !ok { - return nil, nil - } - me := MenuEntry{} SetPageValues(&me, p) diff --git a/parser/pageparser/pagelexer.go b/parser/pageparser/pagelexer.go index 5f90e3687b3..e3b0f1e5468 100644 --- a/parser/pageparser/pagelexer.go +++ b/parser/pageparser/pagelexer.go @@ -62,7 +62,9 @@ func (l *pageLexer) Input() []byte { return l.input } -type Config struct{} +type Config struct { + NoFrontMatter bool +} // note: the input position here is normally 0 (start), but // can be set if position of first shortcode is known diff --git a/parser/pageparser/pageparser.go b/parser/pageparser/pageparser.go index 9e8b6d8032b..988a80c83cf 100644 --- a/parser/pageparser/pageparser.go +++ b/parser/pageparser/pageparser.go @@ -36,7 +36,11 @@ var _ Result = (*pageLexer)(nil) // ParseBytes parses the page in b according to the given Config. func ParseBytes(b []byte, cfg Config) (Items, error) { - l, err := parseBytes(b, cfg, lexIntroSection) + startLexer := lexIntroSection + if cfg.NoFrontMatter { + startLexer = lexMainSection + } + l, err := parseBytes(b, cfg, startLexer) if err != nil { return nil, err } diff --git a/resources/page/pagemeta/page_frontmatter.go b/resources/page/pagemeta/page_frontmatter.go index 10ba2a991af..c901ab57b5f 100644 --- a/resources/page/pagemeta/page_frontmatter.go +++ b/resources/page/pagemeta/page_frontmatter.go @@ -101,6 +101,7 @@ type PageConfig struct { Cascade []map[string]any Sitemap config.SitemapConfig Build BuildConfig + Menus []string // User defined params. Params maps.Params