Repository: gohugoio/hugo
Pull request #13615 (2025-04-15 08:23:29)

build(deps): bump github.com/yuin/goldmark from 1.7.8 to 1.7.9
Bumps [github.com/yuin/goldmark](https://github.com/yuin/goldmark) from 1.7.8 to 1.7.9.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/yuin/goldmark/commit/6951ff3bd1825c85dc9a0197ff9b33825588c26f"><code>6951ff3</code></a> Improve static map builds</li>
<li><a href="https://github.com/yuin/goldmark/commit/04410ff159c9f5fd61c2988402355e44ec9197f5"><code>04410ff</code></a> Merge pull request <a href="https://redirect.github.com/yuin/goldmark/issues/487">#487</a> from n-peugnet/patch-1</li>
<li><a href="https://github.com/yuin/goldmark/commit/f7b2d24c09963f313ff7928d54588ba9af5ebcf0"><code>f7b2d24</code></a> Merge pull request <a href="https://redirect.github.com/yuin/goldmark/issues/489">#489</a> from lyricat/master</li>
<li><a href="https://github.com/yuin/goldmark/commit/ba49c5c69d80d456eea475ee1f818847ef4b67ed"><code>ba49c5c</code></a> Merge pull request <a href="https://redirect.github.com/yuin/goldmark/issues/1">#1</a> from lyricat/lyricat-patch-enclave</li>
<li><a href="https://github.com/yuin/goldmark/commit/c05fb087a4843c521b96542ad01876626d50bbad"><code>c05fb08</code></a> Update README.md</li>
<li><a href="https://github.com/yuin/goldmark/commit/b39daae79e1510cba6ce8471de488d8e5c74dc8b"><code>b39daae</code></a> Fix GitHub actions badge URL</li>
<li>See full diff in <a href="https://github.com/yuin/goldmark/compare/v1.7.8...v1.7.9">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/yuin/goldmark&package-manager=go_modules&previous-version=1.7.8&new-version=1.7.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/common/paths/pathparser.go b/common/paths/pathparser.go
index 4b3feaa14..c04f2022e 100644
--- a/common/paths/pathparser.go
+++ b/common/paths/pathparser.go
@@ -724,7 +724,7 @@ func (p *Path) IsContentData() bool {
 	return p.pathType == TypeContentData
 }
 
-func (p Path) ForBundleType(t Type) *Path {
+func (p Path) ForType(t Type) *Path {
 	p.pathType = t
 	return &p
 }
diff --git a/go.mod b/go.mod
index 9423c6f68..7ac1780d5 100644
--- a/go.mod
+++ b/go.mod
@@ -69,7 +69,7 @@ require (
 	github.com/tdewolff/minify/v2 v2.20.37
 	github.com/tdewolff/parse/v2 v2.7.15
 	github.com/tetratelabs/wazero v1.9.0
-	github.com/yuin/goldmark v1.7.8
+	github.com/yuin/goldmark v1.7.9
 	github.com/yuin/goldmark-emoji v1.0.5
 	go.uber.org/automaxprocs v1.5.3
 	gocloud.dev v0.40.0
diff --git a/go.sum b/go.sum
index 5712679f0..234dc465f 100644
--- a/go.sum
+++ b/go.sum
@@ -467,8 +467,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
-github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
-github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
+github.com/yuin/goldmark v1.7.9 h1:rVSeT+f7/lAM+bJHVm5YHGwNrnd40i1Ch2DEocEjHQ0=
+github.com/yuin/goldmark v1.7.9/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
 github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk=
 github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go
index b501cd9ea..c51b4a17a 100644
--- a/hugolib/content_map_page.go
+++ b/hugolib/content_map_page.go
@@ -180,7 +180,7 @@ func (t *pageTrees) collectAndMarkStaleIdentities(p *paths.Path) []identity.Iden
 
 	if p.Component() == files.ComponentFolderContent {
 		// It may also be a bundled content resource.
-		key := p.ForBundleType(paths.TypeContentResource).Base()
+		key := p.ForType(paths.TypeContentResource).Base()
 		tree = t.treeResources
 		nCount = 0
 		tree.ForEeachInDimension(key, doctree.DimensionLanguage.Index(),


Test patch:
diff --git a/tpl/tplimpl/templatestore.go b/tpl/tplimpl/templatestore.go
index bb58c9083..4266e274a 100644
--- a/tpl/tplimpl/templatestore.go
+++ b/tpl/tplimpl/templatestore.go
@@ -564,14 +564,21 @@ func (s *TemplateStore) LookupPagesLayout(q TemplateQuery) *TemplInfo {
 
 func (s *TemplateStore) LookupPartial(pth string) *TemplInfo {
 	ti, _ := s.cacheLookupPartials.GetOrCreate(pth, func() (*TemplInfo, error) {
-		d := s.templateDescriptorFromPath(pth)
-		desc := d.Desc
-		if desc.LayoutFromTemplate != "" {
-			panic("shortcode template descriptor must not have a layout")
+		pi := s.opts.PathParser.Parse(files.ComponentFolderLayouts, pth).ForType(paths.TypePartial)
+		k1, _, _, desc, err := s.toKeyCategoryAndDescriptor(pi)
+		if err != nil {
+			return nil, err
+		}
+		if desc.OutputFormat == "" && desc.MediaType == "" {
+			// Assume HTML.
+			desc.OutputFormat = s.htmlFormat.Name
+			desc.MediaType = s.htmlFormat.MediaType.Type
+			desc.IsPlainText = s.htmlFormat.IsPlainText
 		}
+
 		best := s.getBest()
 		defer s.putBest(best)
-		s.findBestMatchGet(s.key(path.Join(containerPartials, d.Path)), CategoryPartial, nil, desc, best)
+		s.findBestMatchGet(s.key(path.Join(containerPartials, k1)), CategoryPartial, nil, desc, best)
 		return best.templ, nil
 	})
 
@@ -1486,43 +1493,6 @@ type PathTemplateDescriptor struct {
 	Desc TemplateDescriptor
 }
 
-// templateDescriptorFromPath returns a template descriptor from the given path.
-// This is currently used in partial lookups only.
-func (s *TemplateStore) templateDescriptorFromPath(pth string) PathTemplateDescriptor {
-	var (
-		mt media.Type
-		of output.Format
-	)
-
-	// Common cases.
-	dotCount := strings.Count(pth, ".")
-	if dotCount <= 1 {
-		if dotCount == 0 {
-			// Asume HTML.
-			of, mt = s.resolveOutputFormatAndOrMediaType("html", "")
-		} else {
-			pth = strings.TrimPrefix(pth, "/")
-			ext := path.Ext(pth)
-			pth = strings.TrimSuffix(pth, ext)
-			ext = ext[1:]
-			of, mt = s.resolveOutputFormatAndOrMediaType("", ext)
-		}
-	} else {
-		path := s.opts.PathParser.Parse(files.ComponentFolderLayouts, pth)
-		pth = path.PathNoIdentifier()
-		of, mt = s.resolveOutputFormatAndOrMediaType(path.OutputFormat(), path.Ext())
-	}
-
-	return PathTemplateDescriptor{
-		Path: pth,
-		Desc: TemplateDescriptor{
-			OutputFormat: of.Name,
-			MediaType:    mt.Type,
-			IsPlainText:  of.IsPlainText,
-		},
-	}
-}
-
 // resolveOutputFormatAndOrMediaType resolves the output format and/or media type
 // based on the given output format suffix and media type suffix.
 // Either of the suffixes can be empty, and the function will try to find a match
diff --git a/tpl/tplimpl/templatestore_integration_test.go b/tpl/tplimpl/templatestore_integration_test.go
index b302f5bb3..32e1248fe 100644
--- a/tpl/tplimpl/templatestore_integration_test.go
+++ b/tpl/tplimpl/templatestore_integration_test.go
@@ -1163,3 +1163,44 @@ All.
 	// Just make sure it doesn't fail.
 	hugolib.Test(t, files)
 }
+
+func TestPartialsLangIssue13612(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- hugo.toml --
+disableKinds = ['page','section','sitemap','taxonomy','term']
+
+defaultContentLanguage = 'ru'
+defaultContentLanguageInSubdir = true
+
+[languages.ru]
+weight = 1
+
+[languages.en]
+weight = 2
+
+[outputs]
+home = ['html','rss']
+
+-- layouts/_partials/comment.en.html --
+layouts/_partials/comment.en.html
+-- layouts/_partials/comment.en.xml --
+layouts/_partials/comment.en.xml
+-- layouts/_partials/comment.ru.html --
+layouts/_partials/comment.ru.html
+-- layouts/_partials/comment.ru.xml --
+layouts/_partials/comment.ru.xml
+-- layouts/home.html --
+{{ partial (print "comment." (default "ru" .Lang) ".html") . }}
+-- layouts/home.rss.xml --
+{{ partial (print "comment." (default "ru" .Lang) ".xml") . }}
+`
+
+	b := hugolib.Test(t, files)
+
+	b.AssertFileContent("public/en/index.html", "layouts/_partials/comment.en.html")
+	b.AssertFileContent("public/en/index.xml", "layouts/_partials/comment.en.xml")   // fail
+	b.AssertFileContent("public/ru/index.html", "layouts/_partials/comment.ru.html") // fail
+	b.AssertFileContent("public/ru/index.xml", "layouts/_partials/comment.ru.xml")   // fail
+}