Skip to content

Commit 8ac809a

Browse files
committed
Add roles and versions as new dimensions (in addition to language)
Fixes #519
1 parent 927d1ec commit 8ac809a

30 files changed

+966
-247
lines changed

cache/dynacache/dynacache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func GetOrCreatePartition[K comparable, V any](c *Cache, name string, opts Optio
340340
panic("invalid Weight, must be between 1 and 100")
341341
}
342342

343-
if partitionNameRe.FindString(name) != name {
343+
if !partitionNameRe.MatchString(name) {
344344
panic(fmt.Sprintf("invalid partition name %q", name))
345345
}
346346

common/hstrings/strings.go

-5
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,3 @@ func ToString(v any) (string, bool) {
127127
}
128128
return "", false
129129
}
130-
131-
type (
132-
Strings2 [2]string
133-
Strings3 [3]string
134-
)

common/paths/pathparser.go

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package paths
1515

1616
import (
17+
"fmt"
1718
"path"
1819
"path/filepath"
1920
"runtime"
@@ -780,3 +781,12 @@ func HasExt(p string) bool {
780781
}
781782
return false
782783
}
784+
785+
// ValidateIdentifier returns true if the given string is a valid identifier according
786+
// to Hugo's basic path normalization rules.
787+
func ValidateIdentifier(s string) error {
788+
if s == NormalizePathStringBasic(s) {
789+
return nil
790+
}
791+
return fmt.Errorf("must be all lower case and no spaces")
792+
}

common/types/types.go

+7
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,10 @@ func NewBool(b bool) *bool {
143143
type PrintableValueProvider interface {
144144
PrintableValue() any
145145
}
146+
147+
type (
148+
Strings2 [2]string
149+
Strings3 [3]string
150+
Ints2 [2]int
151+
Ints3 [3]int
152+
)

config/allconfig/allconfig.go

+20
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ import (
4040
"github.com/gohugoio/hugo/config/services"
4141
"github.com/gohugoio/hugo/deploy/deployconfig"
4242
"github.com/gohugoio/hugo/helpers"
43+
"github.com/gohugoio/hugo/hugolib/roles"
4344
"github.com/gohugoio/hugo/hugolib/segments"
45+
"github.com/gohugoio/hugo/hugolib/versions"
4446
"github.com/gohugoio/hugo/langs"
4547
"github.com/gohugoio/hugo/markup/markup_config"
4648
"github.com/gohugoio/hugo/media"
@@ -140,6 +142,12 @@ type Config struct {
140142
// The outputformats configuration sections maps a format name (a string) to a configuration object for that format.
141143
OutputFormats *config.ConfigNamespace[map[string]output.OutputFormatConfig, output.Formats] `mapstructure:"-"`
142144

145+
// The roles configuration section contains the top level roles configuration options.
146+
Roles *config.ConfigNamespace[map[string]roles.RoleConfig, roles.Roles] `mapstructure:"-"`
147+
148+
// The versions configuration section contains the top level versions configuration options.
149+
Versions *config.ConfigNamespace[map[string]versions.VersionConfig, versions.Versions] `mapstructure:"-"`
150+
143151
// The outputs configuration section maps a Page Kind (a string) to a slice of output formats.
144152
// This can be overridden in the front matter.
145153
Outputs map[string][]string `mapstructure:"-"`
@@ -551,6 +559,18 @@ type RootConfig struct {
551559
// Set this to true to put all languages below their language ID.
552560
DefaultContentLanguageInSubdir bool
553561

562+
// The default content role to use for the site.
563+
DefaultContentRole string
564+
565+
// Set this to true to put the default role in a subdirectory.
566+
DefaultContentRoleInSubdir bool
567+
568+
// The default content version to use for the site.
569+
DefaultContentVersion string
570+
571+
// Set to true to render the default version in a subdirectory.
572+
DefaultContentVersionInSubdir bool
573+
554574
// The default output format to use for the site.
555575
// If not set, we will use the first output format.
556576
DefaultOutputFormat string

config/allconfig/alldecoders.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ import (
2727
"github.com/gohugoio/hugo/config/security"
2828
"github.com/gohugoio/hugo/config/services"
2929
"github.com/gohugoio/hugo/deploy/deployconfig"
30+
"github.com/gohugoio/hugo/hugolib/roles"
3031
"github.com/gohugoio/hugo/hugolib/segments"
32+
"github.com/gohugoio/hugo/hugolib/versions"
3133
"github.com/gohugoio/hugo/langs"
3234
"github.com/gohugoio/hugo/markup/markup_config"
3335
"github.com/gohugoio/hugo/media"
@@ -69,8 +71,10 @@ var allDecoderSetups = map[string]decodeWeight{
6971
return err
7072
}
7173

72-
// This need to match with Lang which is always lower case.
74+
// This need to match with the map keys, always lower case.
7375
p.c.RootConfig.DefaultContentLanguage = strings.ToLower(p.c.RootConfig.DefaultContentLanguage)
76+
p.c.RootConfig.DefaultContentRole = strings.ToLower(p.c.RootConfig.DefaultContentRole)
77+
p.c.RootConfig.DefaultContentVersion = strings.ToLower(p.c.RootConfig.DefaultContentVersion)
7478

7579
return nil
7680
},
@@ -210,6 +214,24 @@ var allDecoderSetups = map[string]decodeWeight{
210214
return err
211215
},
212216
},
217+
"roles": {
218+
key: "roles",
219+
decode: func(d decodeWeight, p decodeConfig) error {
220+
var err error
221+
m := maps.CleanConfigStringMap(p.p.GetStringMap(d.key))
222+
p.c.Roles, err = roles.DecodeConfig(p.c.RootConfig.DefaultContentRole, m)
223+
return err
224+
},
225+
},
226+
"versions": {
227+
key: "versions",
228+
decode: func(d decodeWeight, p decodeConfig) error {
229+
var err error
230+
m := maps.CleanConfigStringMap(p.p.GetStringMap(d.key))
231+
p.c.Versions, err = versions.DecodeConfig(p.c.RootConfig.DefaultContentVersion, m)
232+
return err
233+
},
234+
},
213235
"params": {
214236
key: "params",
215237
decode: func(d decodeWeight, p decodeConfig) error {

config/allconfig/configlanguage.go

+12
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ func (c ConfigLanguage) GetConfigSection(s string) any {
165165
return c.config.MediaTypes.Config
166166
case "outputFormats":
167167
return c.config.OutputFormats.Config
168+
case "roles":
169+
return c.config.Roles.Config
170+
case "versions":
171+
return c.config.Versions.Config
168172
case "permalinks":
169173
return c.config.Permalinks
170174
case "minify":
@@ -212,6 +216,14 @@ func (c ConfigLanguage) DefaultContentLanguageInSubdir() bool {
212216
return c.config.DefaultContentLanguageInSubdir
213217
}
214218

219+
func (c ConfigLanguage) DefaultContentRoleInSubdir() bool {
220+
return c.config.DefaultContentRoleInSubdir
221+
}
222+
223+
func (c ConfigLanguage) DefaultContentVersionInSubdir() bool {
224+
return c.config.DefaultContentVersionInSubdir
225+
}
226+
215227
func (c ConfigLanguage) SummaryLength() int {
216228
return c.config.SummaryLength
217229
}

config/configProvider.go

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ type AllProvider interface {
5050
IsUglyURLs(section string) bool
5151
DefaultContentLanguage() string
5252
DefaultContentLanguageInSubdir() bool
53+
DefaultContentRoleInSubdir() bool
54+
DefaultContentVersionInSubdir() bool
5355
IsLangDisabled(string) bool
5456
SummaryLength() int
5557
Pagination() Pagination

hugolib/content_map.go

+21-15
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/gohugoio/hugo/common/hugio"
2626
"github.com/gohugoio/hugo/common/paths"
2727
"github.com/gohugoio/hugo/hugofs/files"
28+
"github.com/gohugoio/hugo/hugolib/doctree"
2829
"github.com/gohugoio/hugo/hugolib/pagesfromdata"
2930
"github.com/gohugoio/hugo/identity"
3031
"github.com/gohugoio/hugo/source"
@@ -55,11 +56,11 @@ type contentMapConfig struct {
5556
var _ contentNodeI = (*resourceSource)(nil)
5657

5758
type resourceSource struct {
58-
langIndex int
59-
path *paths.Path
60-
opener hugio.OpenReadSeekCloser
61-
fi hugofs.FileMetaInfo
62-
rc *pagemeta.ResourceConfig
59+
dim doctree.Dimension
60+
path *paths.Path
61+
opener hugio.OpenReadSeekCloser
62+
fi hugofs.FileMetaInfo
63+
rc *pagemeta.ResourceConfig
6364

6465
r resource.Resource
6566
}
@@ -69,8 +70,8 @@ func (r resourceSource) clone() *resourceSource {
6970
return &r
7071
}
7172

72-
func (r *resourceSource) LangIndex() int {
73-
return r.langIndex
73+
func (r *resourceSource) Dim() doctree.Dimension {
74+
return r.dim
7475
}
7576

7677
func (r *resourceSource) MarkStale() {
@@ -109,7 +110,7 @@ func (r *resourceSource) isContentNodeBranch() bool {
109110

110111
var _ contentNodeI = (*resourceSources)(nil)
111112

112-
type resourceSources []*resourceSource
113+
type resourceSources map[doctree.Dimension]*resourceSource
113114

114115
func (n resourceSources) MarkStale() {
115116
for _, r := range n {
@@ -218,6 +219,10 @@ func (m *pageMap) AddFi(fi hugofs.FileMetaInfo, buildConfig *BuildCfg) (pageCoun
218219
return
219220
}
220221

222+
if m == nil {
223+
panic("nil pageMap")
224+
}
225+
221226
insertResource := func(fim hugofs.FileMetaInfo) error {
222227
resourceCount++
223228
pi := fi.Meta().PathInfo
@@ -227,9 +232,9 @@ func (m *pageMap) AddFi(fi hugofs.FileMetaInfo, buildConfig *BuildCfg) (pageCoun
227232
commit := tree.Lock(true)
228233
defer commit()
229234

230-
r := func() (hugio.ReadSeekCloser, error) {
235+
/*r := func() (hugio.ReadSeekCloser, error) {
231236
return fim.Meta().Open()
232-
}
237+
}*/
233238

234239
var rs *resourceSource
235240
if pi.IsContent() {
@@ -251,9 +256,10 @@ func (m *pageMap) AddFi(fi hugofs.FileMetaInfo, buildConfig *BuildCfg) (pageCoun
251256
}
252257
key = pi.Base()
253258

254-
rs = &resourceSource{r: pageResource, langIndex: pageResource.s.languagei}
259+
rs = &resourceSource{r: pageResource, dim: pageResource.s.dim}
255260
} else {
256-
rs = &resourceSource{path: pi, opener: r, fi: fim, langIndex: fim.Meta().LangIndex}
261+
// TODO1
262+
// rs = &resourceSource{path: pi, opener: r, fi: fim, langIndex: fim.Meta().LangIndex}
257263
}
258264

259265
_, _, _ = m.insertResource(key, rs)
@@ -331,7 +337,7 @@ func (m *pageMap) addPagesFromGoTmplFi(fi hugofs.FileMetaInfo, buildConfig *Buil
331337
return
332338
}
333339

334-
s := m.s.h.resolveSite(fi.Meta().Lang)
340+
s := m.s.h.resolveSite(fi.Meta().Lang, nil, nil) // TODO1 versions, roles.
335341
f := source.NewFileInfo(fi)
336342
h := s.h
337343

@@ -356,7 +362,7 @@ func (m *pageMap) addPagesFromGoTmplFi(fi hugofs.FileMetaInfo, buildConfig *Buil
356362
Watching: s.Conf.Watching(),
357363
HandlePage: func(pt *pagesfromdata.PagesFromTemplate, pc *pagemeta.PageConfig) error {
358364
s := pt.Site.(*Site)
359-
if err := pc.Compile(pt.GoTmplFi.Meta().PathInfo.Base(), true, "", s.Log, s.conf.MediaTypes.Config); err != nil {
365+
if err := pc.Compile(pt.GoTmplFi.Meta().PathInfo.Base(), true, "", s.Log, s.Conf); err != nil {
360366
return err
361367
}
362368

@@ -415,7 +421,7 @@ func (m *pageMap) addPagesFromGoTmplFi(fi hugofs.FileMetaInfo, buildConfig *Buil
415421
return err
416422
}
417423

418-
rs := &resourceSource{path: rc.PathInfo, rc: rc, opener: nil, fi: pt.GoTmplFi, langIndex: s.languagei}
424+
rs := &resourceSource{path: rc.PathInfo, rc: rc, opener: nil, fi: pt.GoTmplFi, dim: s.dim}
419425

420426
_, n, replaced := s.pageMap.insertResourceWithLock(rc.PathInfo.Base(), rs)
421427

0 commit comments

Comments
 (0)