]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Fix language handling in shortcode templates
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 31 May 2025 08:06:13 +0000 (10:06 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 31 May 2025 11:57:00 +0000 (13:57 +0200)
Fixes #13767

common/paths/pathparser.go
common/paths/pathparser_test.go
tpl/tplimpl/shortcodes_integration_test.go

index d10523a848a92aa3a6b277b362854e3be403f26f..1cae710e8f1fe9522521f01724ed0f3eb4fae3d1 100644 (file)
@@ -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--
                }
        }
 
index ad76b93672676090c17c88e109686b2bb7e1c7e7..b1734aef2d0e140773296b3c73314e86cf0b8378 100644 (file)
@@ -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))
index 275e8cc15055b38b9fddf790fa9c9ac71b5f54d8..86f6007caa444977bb161679de405d681dc1cf97 100644 (file)
@@ -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")
+}