diff --git a/common/paths/pathparser.go b/common/paths/pathparser.go index d10523a84..1cae710e8 100644 --- a/common/paths/pathparser.go +++ b/common/paths/pathparser.go @@ -120,7 +120,7 @@ func (pp *PathParser) parse(component, s string) (*Path, error) { return p, nil } -func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot, numDots int) { +func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot, numDots int, isLast bool) { if p.posContainerHigh != -1 { return } @@ -128,7 +128,12 @@ func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot, mayHaveLang = mayHaveLang && (component == files.ComponentFolderContent || component == files.ComponentFolderLayouts) mayHaveOutputFormat := component == files.ComponentFolderLayouts mayHaveKind := p.posIdentifierKind == -1 && mayHaveOutputFormat - mayHaveLayout := component == files.ComponentFolderLayouts + var mayHaveLayout bool + if p.pathType == TypeShortcode { + mayHaveLayout = !isLast && component == files.ComponentFolderLayouts + } else { + mayHaveLayout = component == files.ComponentFolderLayouts + } var found bool var high int @@ -235,19 +240,22 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) { lastDot := 0 lastSlashIdx := strings.LastIndex(s, "/") numDots := strings.Count(s[lastSlashIdx+1:], ".") + if strings.Contains(s, "/_shortcodes/") { + p.pathType = TypeShortcode + } for i := len(s) - 1; i >= 0; i-- { c := s[i] switch c { case '.': - pp.parseIdentifier(component, s, p, i, lastDot, numDots) + pp.parseIdentifier(component, s, p, i, lastDot, numDots, false) lastDot = i case '/': slashCount++ if p.posContainerHigh == -1 { if lastDot > 0 { - pp.parseIdentifier(component, s, p, i, lastDot, numDots) + pp.parseIdentifier(component, s, p, i, lastDot, numDots, true) } p.posContainerHigh = i + 1 } else if p.posContainerLow == -1 { @@ -283,10 +291,9 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) { p.pathType = TypeContentData } } - } - if component == files.ComponentFolderLayouts { + if p.pathType < TypeMarkup && component == files.ComponentFolderLayouts { if p.posIdentifierBaseof != -1 { p.pathType = TypeBaseof } else { @@ -302,12 +309,10 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) { } if p.pathType == TypeShortcode && p.posIdentifierLayout != -1 { - // myshortcode or myshortcode.html, no layout. - if len(p.identifiersKnown) <= 2 { + id := p.identifiersKnown[p.posIdentifierLayout] + if id.Low == p.posContainerHigh { + // First identifier is shortcode name. p.posIdentifierLayout = -1 - } else { - // First is always the name. - p.posIdentifierLayout-- } } diff --git a/common/paths/pathparser_test.go b/common/paths/pathparser_test.go index ad76b9367..b1734aef2 100644 --- a/common/paths/pathparser_test.go +++ b/common/paths/pathparser_test.go @@ -434,12 +434,12 @@ func TestParseLayouts(t *testing.T) { }, { "Layout multiple", - "/maylayout.list.section.no.html", + "/mylayout.list.section.no.html", func(c *qt.C, p *Path) { - c.Assert(p.Layout(), qt.Equals, "maylayout") - c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "no", "section", "list", "maylayout"}) + c.Assert(p.Layout(), qt.Equals, "mylayout") + c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "no", "section", "list", "mylayout"}) c.Assert(p.IdentifiersUnknown(), qt.DeepEquals, []string{}) - c.Assert(p.Base(), qt.Equals, "/maylayout.html") + c.Assert(p.Base(), qt.Equals, "/mylayout.html") c.Assert(p.Lang(), qt.Equals, "no") }, }, @@ -487,7 +487,8 @@ func TestParseLayouts(t *testing.T) { func(c *qt.C, p *Path) { c.Assert(p.Base(), qt.Equals, "/_shortcodes/myshortcode.html") c.Assert(p.Type(), qt.Equals, TypeShortcode) - c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "list", "myshortcode"}) + c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "list"}) + c.Assert(p.Layout(), qt.Equals, "list") c.Assert(p.PathNoIdentifier(), qt.Equals, "/_shortcodes/myshortcode") c.Assert(p.PathBeforeLangAndOutputFormatAndExt(), qt.Equals, "/_shortcodes/myshortcode.list") c.Assert(p.Lang(), qt.Equals, "") @@ -572,11 +573,21 @@ func TestParseLayouts(t *testing.T) { c.Assert(p.NameNoIdentifier(), qt.Equals, "no") }, }, + { + "Shortcode lang layout", + "/_shortcodes/myshortcode.no.html", + func(c *qt.C, p *Path) { + c.Assert(p.Type(), qt.Equals, TypeShortcode) + c.Assert(p.Lang(), qt.Equals, "no") + c.Assert(p.Layout(), qt.Equals, "") + c.Assert(p.NameNoIdentifier(), qt.Equals, "myshortcode") + }, + }, } for _, test := range tests { c.Run(test.name, func(c *qt.C) { - if test.name != "Shortcode lang in root" { + if test.name != "Shortcode lang layout" { // return } test.assert(c, testParser.Parse(files.ComponentFolderLayouts, test.path)) diff --git a/tpl/tplimpl/shortcodes_integration_test.go b/tpl/tplimpl/shortcodes_integration_test.go index 275e8cc15..86f6007ca 100644 --- a/tpl/tplimpl/shortcodes_integration_test.go +++ b/tpl/tplimpl/shortcodes_integration_test.go @@ -757,3 +757,40 @@ title: home b.AssertFileContent("public/index.html", "de.html") } + +func TestShortcodeLanguage13767(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +defaultContentLanguage = 'pl' +defaultContentLanguageInSubdir = true +[languages.pl] +weight = 1 +[languages.en] +weight = 2 +-- content/_index.md -- +--- +title: dom +--- +{{< myshortcode >}} +-- content/_index.en.md -- +--- +title: home +--- +{{< myshortcode >}} +-- layouts/_shortcodes/myshortcode.html -- +myshortcode.html +-- layouts/_shortcodes/myshortcode.en.html -- +myshortcode.en.html +-- layouts/all.html -- +{{ .Content }} + + +` + + b := hugolib.Test(t, files) + + b.AssertFileContent("public/pl/index.html", "myshortcode.html") + b.AssertFileContent("public/en/index.html", "myshortcode.en.html") +}