mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-27 22:09:53 +02:00
resources/page: Expand parmalinks tokens in url
This change allows to use permalink tokens in url front matter fields. This should be useful to target more specific pages instead of using a global permalink configuration. It's expected to be used with cascade. Fixes #9714
This commit is contained in:
@@ -40,6 +40,8 @@ type PermalinkExpander struct {
|
||||
expanders map[string]map[string]func(Page) (string, error)
|
||||
|
||||
urlize func(uri string) string
|
||||
|
||||
patternCache *maps.Cache[string, func(Page) (string, error)]
|
||||
}
|
||||
|
||||
// Time for checking date formats. Every field is different than the
|
||||
@@ -71,7 +73,10 @@ func (p PermalinkExpander) callback(attr string) (pageToPermaAttribute, bool) {
|
||||
// NewPermalinkExpander creates a new PermalinkExpander configured by the given
|
||||
// urlize func.
|
||||
func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]map[string]string) (PermalinkExpander, error) {
|
||||
p := PermalinkExpander{urlize: urlize}
|
||||
p := PermalinkExpander{
|
||||
urlize: urlize,
|
||||
patternCache: maps.NewCache[string, func(Page) (string, error)](),
|
||||
}
|
||||
|
||||
p.knownPermalinkAttributes = map[string]pageToPermaAttribute{
|
||||
"year": p.pageToPermalinkDate,
|
||||
@@ -102,6 +107,16 @@ func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]ma
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ExpandPattern expands the path in p with the specified expand pattern.
|
||||
func (l PermalinkExpander) ExpandPattern(pattern string, p Page) (string, error) {
|
||||
expander, err := l.getOrParsePattern(pattern)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return expander(p)
|
||||
}
|
||||
|
||||
// Expand expands the path in p according to the rules defined for the given key.
|
||||
// If no rules are found for the given key, an empty string is returned.
|
||||
func (l PermalinkExpander) Expand(key string, p Page) (string, error) {
|
||||
@@ -129,17 +144,11 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (l PermalinkExpander) parse(patterns map[string]string) (map[string]func(Page) (string, error), error) {
|
||||
expanders := make(map[string]func(Page) (string, error))
|
||||
|
||||
for k, pattern := range patterns {
|
||||
k = strings.Trim(k, sectionCutSet)
|
||||
|
||||
func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string, error), error) {
|
||||
return l.patternCache.GetOrCreate(pattern, func() (func(Page) (string, error), error) {
|
||||
if !l.validate(pattern) {
|
||||
return nil, &permalinkExpandError{pattern: pattern, err: errPermalinkIllFormed}
|
||||
}
|
||||
|
||||
pattern := pattern
|
||||
matches := attributeRegexp.FindAllStringSubmatch(pattern, -1)
|
||||
|
||||
callbacks := make([]pageToPermaAttribute, len(matches))
|
||||
@@ -157,7 +166,7 @@ func (l PermalinkExpander) parse(patterns map[string]string) (map[string]func(Pa
|
||||
callbacks[i] = callback
|
||||
}
|
||||
|
||||
expanders[k] = func(p Page) (string, error) {
|
||||
return func(p Page) (string, error) {
|
||||
if matches == nil {
|
||||
return pattern, nil
|
||||
}
|
||||
@@ -173,12 +182,25 @@ func (l PermalinkExpander) parse(patterns map[string]string) (map[string]func(Pa
|
||||
}
|
||||
|
||||
newField = strings.Replace(newField, replacement, newAttr, 1)
|
||||
|
||||
}
|
||||
|
||||
return newField, nil
|
||||
}, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (l PermalinkExpander) parse(patterns map[string]string) (map[string]func(Page) (string, error), error) {
|
||||
expanders := make(map[string]func(Page) (string, error))
|
||||
|
||||
for k, pattern := range patterns {
|
||||
k = strings.Trim(k, sectionCutSet)
|
||||
|
||||
expander, err := l.getOrParsePattern(pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expanders[k] = expander
|
||||
}
|
||||
|
||||
return expanders, nil
|
||||
|
Reference in New Issue
Block a user