mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-24 15:28:54 +00:00
Fix filename dimension identifiers (_role_X_, _version_X_) to replace mount config
Filename identifiers for roles and versions were parsed but never applied to the SitesMatrix. Now they replace the mount's configuration for that dimension, matching how language identifiers already worked. Fixes #14756 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+25
-3
@@ -320,8 +320,9 @@ func (fs *componentFs) applyMeta(fi FileNameIsDir, name string) (FileMetaInfo, b
|
||||
|
||||
meta.PathInfo = pi
|
||||
if !fim.IsDir() {
|
||||
pp := fs.opts.Cfg.PathParser()
|
||||
if fileLang := meta.PathInfo.Lang(); fileLang != "" {
|
||||
if idx, ok := fs.opts.Cfg.PathParser().LanguageIndex[fileLang]; ok {
|
||||
if idx, ok := pp.LanguageIndex[fileLang]; ok {
|
||||
// A valid lang set in filename.
|
||||
// Give priority to myfile.sv.txt inside the sv filesystem.
|
||||
meta.Weight++
|
||||
@@ -330,7 +331,29 @@ func (fs *componentFs) applyMeta(fi FileNameIsDir, name string) (FileMetaInfo, b
|
||||
// Not the default language, add some weight.
|
||||
meta.SitesMatrix = sitesmatrix.NewWeightedVectorStore(meta.SitesMatrix, 10)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Filename identifiers for roles/versions replace any mount configuration for that dimension.
|
||||
if roles := pi.Roles(); len(roles) > 0 {
|
||||
var indices []int
|
||||
for _, role := range roles {
|
||||
if idx := pp.ConfiguredDimensions.ConfiguredRoles.ResolveIndex(role); idx >= 0 {
|
||||
indices = append(indices, idx)
|
||||
}
|
||||
}
|
||||
if len(indices) > 0 {
|
||||
meta.SitesMatrix = meta.SitesMatrix.WithRoleIndices(indices...)
|
||||
}
|
||||
}
|
||||
if versions := pi.Versions(); len(versions) > 0 {
|
||||
var indices []int
|
||||
for _, version := range versions {
|
||||
if idx := pp.ConfiguredDimensions.ConfiguredVersions.ResolveIndex(version); idx >= 0 {
|
||||
indices = append(indices, idx)
|
||||
}
|
||||
}
|
||||
if len(indices) > 0 {
|
||||
meta.SitesMatrix = meta.SitesMatrix.WithVersionIndices(indices...)
|
||||
}
|
||||
}
|
||||
switch meta.Component {
|
||||
@@ -341,7 +364,6 @@ func (fs *componentFs) applyMeta(fi FileNameIsDir, name string) (FileMetaInfo, b
|
||||
meta.Weight--
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
|
||||
@@ -214,7 +214,9 @@ type VectorProvider interface {
|
||||
type VectorStore interface {
|
||||
VectorProvider
|
||||
Complement(...VectorProvider) VectorStore
|
||||
WithLanguageIndices(i int) VectorStore
|
||||
WithLanguageIndices(i ...int) VectorStore
|
||||
WithVersionIndices(i ...int) VectorStore
|
||||
WithRoleIndices(i ...int) VectorStore
|
||||
HasLanguage(lang int) bool
|
||||
HasVersion(version int) bool
|
||||
HasRole(role int) bool
|
||||
|
||||
@@ -1901,3 +1901,55 @@ title: p1 de
|
||||
</ul>
|
||||
`)
|
||||
}
|
||||
|
||||
// Issue 14756.
|
||||
func TestFilenameIdentifierShouldReplaceMountDimension(t *testing.T) {
|
||||
t.Parallel()
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
baseURL = "https://example.org/"
|
||||
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
|
||||
defaultContentLanguage = "en"
|
||||
defaultContentRole = "guest"
|
||||
defaultContentRoleInSubdir = true
|
||||
[roles]
|
||||
[roles.guest]
|
||||
weight = 100
|
||||
[roles.member]
|
||||
weight = 200
|
||||
[module]
|
||||
[[module.mounts]]
|
||||
source = 'content/member'
|
||||
target = 'content'
|
||||
[module.mounts.sites.matrix]
|
||||
roles = "member"
|
||||
[[module.mounts]]
|
||||
source = 'content/guest'
|
||||
target = 'content'
|
||||
[module.mounts.sites.matrix]
|
||||
roles = "*"
|
||||
-- content/member/bundle/index.md --
|
||||
---
|
||||
title: "Bundle"
|
||||
---
|
||||
-- content/guest/bundle/index.md --
|
||||
---
|
||||
title: "Bundle"
|
||||
---
|
||||
-- content/guest/bundle/img._role_member_.txt --
|
||||
memberimg
|
||||
-- content/guest/bundle/guestimg.txt --
|
||||
guestimg
|
||||
-- layouts/page.html --
|
||||
Role: {{ .Site.Role.Name }}|{{ range .Resources }}{{ .Name }}|{{ end }}$
|
||||
-- layouts/list.html --
|
||||
List.
|
||||
`
|
||||
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
// The guest role should only see guestimg.txt (not img._role_member_.txt).
|
||||
b.AssertFileContent("public/guest/bundle/index.html", "Role: guest|guestimg.txt|$")
|
||||
// The member role should see both.
|
||||
b.AssertFileContent("public/member/bundle/index.html", "Role: member|guestimg.txt|img._role_member_.txt|$")
|
||||
}
|
||||
|
||||
@@ -209,17 +209,46 @@ func (s *vectorStoreMap) Vectors() []Vector {
|
||||
return vectors
|
||||
}
|
||||
|
||||
func (s *vectorStoreMap) WithLanguageIndices(i int) VectorStore {
|
||||
func (s *vectorStoreMap) WithLanguageIndices(i ...int) VectorStore {
|
||||
c := s.clone()
|
||||
|
||||
for v := range c.sets {
|
||||
v[Language] = i
|
||||
c.sets[v] = struct{}{}
|
||||
for _, i := range i {
|
||||
nv := v
|
||||
nv[Language] = i
|
||||
c.sets[nv] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (s *vectorStoreMap) WithVersionIndices(indices ...int) VectorStore {
|
||||
old := s.clone()
|
||||
c := newVectorStoreMap(len(old.sets) * len(indices))
|
||||
for v := range old.sets {
|
||||
for _, i := range indices {
|
||||
nv := v
|
||||
nv[Version] = i
|
||||
c.sets[nv] = struct{}{}
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (s *vectorStoreMap) WithRoleIndices(indices ...int) VectorStore {
|
||||
old := s.clone()
|
||||
c := newVectorStoreMap(len(old.sets) * len(indices))
|
||||
for v := range old.sets {
|
||||
for _, i := range indices {
|
||||
nv := v
|
||||
nv[Role] = i
|
||||
c.sets[nv] = struct{}{}
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (s *vectorStoreMap) HasLanguage(i int) bool {
|
||||
for v := range s.sets {
|
||||
if v.Language() == i {
|
||||
@@ -589,10 +618,24 @@ func (s IntSets) shallowClone() *IntSets {
|
||||
return &s
|
||||
}
|
||||
|
||||
// WithLanguageIndices replaces the current language set with a single language index.
|
||||
func (s *IntSets) WithLanguageIndices(i int) VectorStore {
|
||||
// WithLanguageIndices replaces the current language set with the given language indices.
|
||||
func (s *IntSets) WithLanguageIndices(indices ...int) VectorStore {
|
||||
c := s.shallowClone()
|
||||
c.languages = hmaps.NewOrderedIntSet(i)
|
||||
c.languages = hmaps.NewOrderedIntSet(indices...)
|
||||
return c.init()
|
||||
}
|
||||
|
||||
// WithVersionIndices replaces the current version set with the given version indices.
|
||||
func (s *IntSets) WithVersionIndices(indices ...int) VectorStore {
|
||||
c := s.shallowClone()
|
||||
c.versions = hmaps.NewOrderedIntSet(indices...)
|
||||
return c.init()
|
||||
}
|
||||
|
||||
// WithRoleIndices replaces the current role set with the given role indices.
|
||||
func (s *IntSets) WithRoleIndices(indices ...int) VectorStore {
|
||||
c := s.shallowClone()
|
||||
c.roles = hmaps.NewOrderedIntSet(indices...)
|
||||
return c.init()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user