Skip to content

Commit 01f9c33

Browse files
committed
Work
1 parent d230e3d commit 01f9c33

File tree

9 files changed

+177
-74
lines changed

9 files changed

+177
-74
lines changed

‎config/allconfig/alldecoders.go‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,14 @@ var allDecoderSetups = map[string]decodeWeight{
217217
"roles": {
218218
key: "roles",
219219
decode: func(d decodeWeight, p decodeConfig) error {
220-
var err error
220+
var (
221+
err error
222+
defaultContentRole string
223+
)
221224
m := maps.CleanConfigStringMap(p.p.GetStringMap(d.key))
222-
p.c.Roles, err = roles.DecodeConfig(p.c.RootConfig.DefaultContentRole, m)
225+
p.c.Roles, defaultContentRole, err = roles.DecodeConfig(p.c.RootConfig.DefaultContentRole, m)
226+
p.c.RootConfig.DefaultContentRole = defaultContentRole
227+
223228
return err
224229
},
225230
},

‎hugolib/cascade_test.go‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,3 +917,47 @@ title: p2
917917
b.AssertFileExists("public/sx/index.html", true) // failing
918918
b.AssertFileExists("public/sx/p2/index.html", true) // failing
919919
}
920+
921+
func TestDimensionsCascadeConfig(t *testing.T) {
922+
files := `
923+
-- hugo.toml --
924+
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
925+
[languages]
926+
[languages.en]
927+
weight = 1
928+
[languages.nn]
929+
weight = 2
930+
[languages.sv]
931+
weight = 3
932+
933+
[versions]
934+
[versions.v1.0.0]
935+
[versions.v2.0.0]
936+
937+
[cascade]
938+
languages = ["en*"]
939+
languageDelegees = ["nn*"]
940+
versions = ["v1*"]
941+
versionDelegees = ["v2*"]
942+
roles = ["guest*"]
943+
roleDelegees = ["member*"]
944+
-- content/_index.md --
945+
---
946+
title: "Home"
947+
---
948+
-- layouts/all.html --
949+
All.
950+
951+
`
952+
953+
b := Test(t, files)
954+
b.Assert(len(b.H.Sites), qt.Equals, 1)
955+
956+
homeEn := b.H.Sites[0].Home().(*pageState)
957+
b.Assert(homeEn.m.pageConfig.Versions, qt.DeepEquals, []string{"v1*"})
958+
b.Assert(homeEn.m.pageConfig.VersionDelegees, qt.DeepEquals, []string{"v2*"})
959+
b.Assert(homeEn.m.pageConfig.Roles, qt.DeepEquals, []string{"guest*"})
960+
b.Assert(homeEn.m.pageConfig.RoleDelegees, qt.DeepEquals, []string{"member*"})
961+
b.Assert(homeEn.m.pageConfig.Languages, qt.DeepEquals, []string{"en*"})
962+
b.Assert(homeEn.m.pageConfig.LanguageDelegees, qt.DeepEquals, []string{"nn*"})
963+
}

‎hugolib/content_map_test.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"testing"
2222

2323
qt "github.com/frankban/quicktest"
24+
"github.com/gohugoio/hugo/hugolib/doctree"
2425
"github.com/gohugoio/hugo/identity"
2526
)
2627

@@ -508,6 +509,10 @@ func (n *testContentNode) isContentNodeBranch() bool {
508509
func (n *testContentNode) resetBuildState() {
509510
}
510511

512+
func (n *testContentNode) matchDirectOrInDelegees(doctree.Dimensions) (contentNodeI, doctree.Dimensions) {
513+
panic("not implemented")
514+
}
515+
511516
func (n *testContentNode) MarkStale() {
512517
}
513518

‎hugolib/hugo_sites_build.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
161161
}
162162
}
163163

164-
for _, s := range h.Sites {
164+
for s := range h.allSites() {
165165
s.state = siteStateReady
166166
}
167167

‎hugolib/page__meta.go‎

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -251,65 +251,15 @@ func (p *pageMeta) setMetaPre(pi *contentParseInfo, logger loggers.Logger, conf
251251
frontmatter := pi.frontMatter
252252

253253
if frontmatter != nil {
254-
pcfg := p.pageConfig
255-
// Needed for case insensitive fetching of params values
256-
maps.PrepareParams(frontmatter)
257-
pcfg.Params = frontmatter
258-
// Check for any cascade define on itself.
259-
if cv, found := frontmatter["cascade"]; found {
260-
var err error
261-
cascade, err := page.DecodeCascade(logger, true, cv)
262-
if err != nil {
263-
return err
264-
}
265-
pcfg.CascadeCompiled = cascade
266-
}
267-
268-
// Look for path, lang, roles and kind, all of which values we need early on.
269-
if v, found := frontmatter["path"]; found {
270-
pcfg.Path = paths.ToSlashPreserveLeading(cast.ToString(v))
271-
}
272-
if v, found := frontmatter["lang"]; found {
273-
lang := strings.ToLower(cast.ToString(v))
274-
if _, ok := conf.PathParser().LanguageIndex[lang]; ok {
275-
pcfg.Lang = lang
276-
}
277-
}
278-
if v, found := frontmatter["kind"]; found {
279-
s := cast.ToString(v)
280-
if s != "" {
281-
pcfg.Kind = kinds.GetKindMain(s)
282-
if pcfg.Kind == "" {
283-
return fmt.Errorf("unknown kind %q in front matter", s)
284-
}
285-
}
286-
}
287-
if v, found := frontmatter["roles"]; found {
288-
pcfg.Roles = cast.ToStringSlice(v)
289-
}
290-
if v, found := frontmatter["versions"]; found {
291-
pcfg.Versions = cast.ToStringSlice(v)
292-
}
293-
if v, found := frontmatter["languages"]; found {
294-
pcfg.Languages = cast.ToStringSlice(v)
295-
}
296-
if v, found := frontmatter["languagedelegees"]; found {
297-
pcfg.LanguageDelegees = cast.ToStringSlice(v)
298-
}
299-
if v, found := frontmatter["versiondelegees"]; found {
300-
pcfg.VersionDelegees = cast.ToStringSlice(v)
301-
}
302-
if v, found := frontmatter["roledelegees"]; found {
303-
pcfg.RoleDelegees = cast.ToStringSlice(v)
254+
if err := p.pageConfig.SetMetaPreFromMap(frontmatter, logger, conf); err != nil {
255+
return err
304256
}
305-
306257
} else if p.pageMetaParams.pageConfig.Params == nil {
307258
p.pageConfig.Params = make(maps.Params)
308259
}
309260

310261
p.pageMetaParams.init(conf.Watching())
311262

312-
// TODO1 check if we can allow cascade from config.
313263
if err := p.pageConfig.CompileEearly(conf); err != nil {
314264
return fmt.Errorf("failed to compile roles: %w", err)
315265
}

‎hugolib/roles/roles.go‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,27 @@ func (r RolesInternal) IndexMatch(filter predicate.Filter[string]) (iter.Seq[int
102102
}, nil
103103
}
104104

105-
func (r *RolesInternal) init(defaultContentRole string) error {
105+
const dfaultContentRoleFallback = "guest"
106+
107+
func (r *RolesInternal) init(defaultContentRole string) (string, error) {
106108
if len(r.roleConfigs) == 0 {
107109
// Add a default role.
108-
r.roleConfigs[""] = RoleConfig{}
110+
if defaultContentRole == "" {
111+
defaultContentRole = dfaultContentRoleFallback
112+
}
113+
r.roleConfigs[defaultContentRole] = RoleConfig{}
109114
}
110115

111116
var defaultSeen bool
112117
for k, v := range r.roleConfigs {
113118
if k == "" {
114-
return errors.New("role name cannot be empty")
119+
return "", errors.New("role name cannot be empty")
115120
}
116121

117122
if err := paths.ValidateIdentifier(k); err != nil {
118123
// TODO1 config keys gets auto lowercased, so this will (almost) never happen.
119124
// TODO1: Tree store: linked list for dimension nodes.
120-
return fmt.Errorf("role name %q is invalid: %s", k, err)
125+
return "", fmt.Errorf("role name %q is invalid: %s", k, err)
121126
}
122127

123128
var isDefault bool
@@ -150,27 +155,31 @@ func (r *RolesInternal) init(defaultContentRole string) error {
150155
first.Default = true
151156
r.roleConfigs[first.Name] = first.RoleConfig
152157
r.Sorted[0] = first
158+
defaultContentRole = first.Name
153159
}
154160

155-
return nil
161+
return defaultContentRole, nil
156162
}
157163

158164
func (r RolesInternal) Has(role string) bool {
159165
_, found := r.roleConfigs[role]
160166
return found
161167
}
162168

163-
func DecodeConfig(defaultContentRole string, m map[string]any) (*config.ConfigNamespace[map[string]RoleConfig, RolesInternal], error) {
164-
return config.DecodeNamespace[map[string]RoleConfig](m, func(in any) (RolesInternal, any, error) {
169+
func DecodeConfig(defaultContentRole string, m map[string]any) (*config.ConfigNamespace[map[string]RoleConfig, RolesInternal], string, error) {
170+
v, err := config.DecodeNamespace[map[string]RoleConfig](m, func(in any) (RolesInternal, any, error) {
165171
var roles RolesInternal
166172
var conf map[string]RoleConfig
167173
if err := mapstructure.Decode(m, &conf); err != nil {
168174
return roles, nil, err
169175
}
170176
roles.roleConfigs = conf
171-
if err := roles.init(defaultContentRole); err != nil {
177+
var err error
178+
if defaultContentRole, err = roles.init(defaultContentRole); err != nil {
172179
return roles, nil, err
173180
}
174181
return roles, nil, nil
175182
})
183+
184+
return v, defaultContentRole, err
176185
}

‎hugolib/roles/roles_integration_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ RegularPages: {{ range .RegularPages }}{{ .RelPermalink }} r: {{ .Site.Language.
8484
8585
`
8686

87-
for range 20 {
87+
for range 3 {
8888
b := hugolib.Test(t, files)
8989

9090
// TODO1 export Default?

‎hugolib/site_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ Content: {{ .Content }}|
10181018

10191019
func checkLinkCase(site *Site, link string, currentPage page.Page, relative bool, outputFormat string, expected string, t *testing.T, i int) {
10201020
t.Helper()
1021-
if out, err := site.refLink(link, currentPage, relative, outputFormat); err != nil || out != expected {
1021+
if out, err := site.siteRefLinker.refLink(link, currentPage, relative, outputFormat); err != nil || out != expected {
10221022
t.Fatalf("[%d] Expected %q from %q to resolve to %q, got %q - error: %s", i, link, currentPage.Path(), expected, out, err)
10231023
}
10241024
}

‎resources/page/pagemeta/page_frontmatter.go‎

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,113 @@ type PageConfigEarly struct {
9696
VersionDelegees []string
9797
LanguageDelegees []string
9898

99+
// User defined params.
100+
Params maps.Params
101+
99102
Cascade []map[string]any
100103

101104
// Content holds the content for this page.
102105
Content Source
106+
107+
// Compiled values.
108+
CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"`
109+
}
110+
111+
const (
112+
pageMetaKeyVersions = "versions"
113+
pageMetaKeyLanguages = "languages"
114+
pageMetaKeyRoles = "roles"
115+
pageMetaKeyVersionDelegees = "versiondelegees"
116+
pageMetaKeyLanguageDelegees = "languagedelegees"
117+
pageMetaKeyRoleDelegees = "roledelegees"
118+
pageMetaKeyCascade = "cascade"
119+
pageMetaKeyPath = "path"
120+
pageMetaKeyLang = "lang"
121+
pageMetaKeyKind = "kind"
122+
)
123+
124+
func (pcfg *PageConfigEarly) SetMetaPreFromMap(frontmatter map[string]any, logger loggers.Logger, conf config.AllProvider) error {
125+
// Needed for case insensitive fetching of params values.
126+
maps.PrepareParams(frontmatter)
127+
pcfg.Params = frontmatter
128+
// Check for any cascade define on itself.
129+
if cv, found := frontmatter[pageMetaKeyCascade]; found {
130+
var err error
131+
cascade, err := page.DecodeCascade(logger, true, cv)
132+
if err != nil {
133+
return err
134+
}
135+
pcfg.CascadeCompiled = cascade
136+
}
137+
138+
// Look for path, lang, roles and kind, all of which values we need early on.
139+
if v, found := frontmatter[pageMetaKeyPath]; found {
140+
pcfg.Path = paths.ToSlashPreserveLeading(cast.ToString(v))
141+
}
142+
if v, found := frontmatter[pageMetaKeyLang]; found {
143+
lang := strings.ToLower(cast.ToString(v))
144+
if _, ok := conf.PathParser().LanguageIndex[lang]; ok {
145+
pcfg.Lang = lang
146+
}
147+
}
148+
if v, found := frontmatter[pageMetaKeyKind]; found {
149+
s := cast.ToString(v)
150+
if s != "" {
151+
pcfg.Kind = kinds.GetKindMain(s)
152+
if pcfg.Kind == "" {
153+
return fmt.Errorf("unknown kind %q in front matter", s)
154+
}
155+
}
156+
}
157+
if v, found := frontmatter[pageMetaKeyRoles]; found {
158+
pcfg.Roles = cast.ToStringSlice(v)
159+
}
160+
if v, found := frontmatter[pageMetaKeyVersions]; found {
161+
pcfg.Versions = cast.ToStringSlice(v)
162+
}
163+
if v, found := frontmatter[pageMetaKeyLanguages]; found {
164+
pcfg.Languages = cast.ToStringSlice(v)
165+
}
166+
if v, found := frontmatter[pageMetaKeyLanguageDelegees]; found {
167+
pcfg.LanguageDelegees = cast.ToStringSlice(v)
168+
}
169+
if v, found := frontmatter[pageMetaKeyVersionDelegees]; found {
170+
pcfg.VersionDelegees = cast.ToStringSlice(v)
171+
}
172+
if v, found := frontmatter[pageMetaKeyRoleDelegees]; found {
173+
pcfg.RoleDelegees = cast.ToStringSlice(v)
174+
}
175+
176+
return nil
103177
}
104178

105179
func (p *PageConfigEarly) setConfigCascadeValueIfNotSet(key string, value any) {
106180
switch key {
107-
// TODO1 complement.
108-
case "versions":
181+
case pageMetaKeyVersions:
109182
if p.Versions == nil {
110183
p.Versions = types.ToStringSlicePreserveString(value)
111184
}
185+
case pageMetaKeyLanguages:
186+
if p.Languages == nil {
187+
p.Languages = types.ToStringSlicePreserveString(value)
188+
}
189+
case pageMetaKeyRoles:
190+
if p.Roles == nil {
191+
p.Roles = types.ToStringSlicePreserveString(value)
192+
}
193+
case pageMetaKeyVersionDelegees:
194+
if p.VersionDelegees == nil {
195+
p.VersionDelegees = types.ToStringSlicePreserveString(value)
196+
}
197+
case pageMetaKeyLanguageDelegees:
198+
if p.LanguageDelegees == nil {
199+
p.LanguageDelegees = types.ToStringSlicePreserveString(value)
200+
}
201+
case pageMetaKeyRoleDelegees:
202+
if p.RoleDelegees == nil {
203+
p.RoleDelegees = types.ToStringSlicePreserveString(value)
204+
}
205+
112206
}
113207
}
114208

@@ -142,18 +236,14 @@ type PageConfig struct {
142236
Build BuildConfig
143237
Menus any // Can be a string, []string or map[string]any.
144238

145-
// User defined params.
146-
Params maps.Params
147-
148239
// The raw data from the content adapter.
149240
// TODO(bep) clean up the ContentAdapterData vs Params.
150241
ContentAdapterData map[string]any `mapstructure:"-" json:"-"`
151242

152243
// Compiled values.
153-
ConfiguredOutputFormats output.Formats `mapstructure:"-" json:"-"`
154-
CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"`
155-
ContentMediaType media.Type `mapstructure:"-" json:"-"`
156-
IsFromContentAdapter bool `mapstructure:"-" json:"-"`
244+
ConfiguredOutputFormats output.Formats `mapstructure:"-" json:"-"`
245+
ContentMediaType media.Type `mapstructure:"-" json:"-"`
246+
IsFromContentAdapter bool `mapstructure:"-" json:"-"`
157247

158248
LanguagesCompiledSet *maps.OrderedIntSet `mapstructure:"-" json:"-"`
159249
RolesCompiledSet *maps.OrderedIntSet `mapstructure:"-" json:"-"`

0 commit comments

Comments
 (0)