mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
resources/page: Adjust the permalinks colon implementation a little
Mostly to get back to an attribute regexp that's reasonably simle to read/understand. Updates #12918
This commit is contained in:
parent
e7d0757f95
commit
6e1c5b61b3
2 changed files with 36 additions and 22 deletions
|
@ -107,44 +107,42 @@ func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]ma
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l PermalinkExpander) normalizeEscapeSequences(result string) string {
|
// Escape sequence for colons in permalink patterns.
|
||||||
return strings.ReplaceAll(result, "\\:", ":")
|
const escapePlaceholderColon = "\x00"
|
||||||
|
|
||||||
|
func (l PermalinkExpander) normalizeEscapeSequencesIn(s string) (string, bool) {
|
||||||
|
s2 := strings.ReplaceAll(s, "\\:", escapePlaceholderColon)
|
||||||
|
return s2, s2 != s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l PermalinkExpander) normalizeEscapeSequencesOut(result string) string {
|
||||||
|
return strings.ReplaceAll(result, escapePlaceholderColon, ":")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExpandPattern expands the path in p with the specified expand pattern.
|
// ExpandPattern expands the path in p with the specified expand pattern.
|
||||||
func (l PermalinkExpander) ExpandPattern(pattern string, p Page) (string, error) {
|
func (l PermalinkExpander) ExpandPattern(pattern string, p Page) (string, error) {
|
||||||
expander, err := l.getOrParsePattern(pattern)
|
expand, err := l.getOrParsePattern(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := expander(p)
|
return expand(p)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return l.normalizeEscapeSequences(result), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand expands the path in p according to the rules defined for the given key.
|
// 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.
|
// If no rules are found for the given key, an empty string is returned.
|
||||||
func (l PermalinkExpander) Expand(key string, p Page) (string, error) {
|
func (l PermalinkExpander) Expand(key string, p Page) (string, error) {
|
||||||
expanders, found := l.expanders[p.Kind()]
|
expanders, found := l.expanders[p.Kind()]
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
expand, found := expanders[key]
|
expand, found := expanders[key]
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := expand(p)
|
return expand(p)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return l.normalizeEscapeSequences(result), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow " " and / to represent the root section.
|
// Allow " " and / to represent the root section.
|
||||||
|
@ -161,12 +159,24 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
|
||||||
if !l.validate(pattern) {
|
if !l.validate(pattern) {
|
||||||
return nil, &permalinkExpandError{pattern: pattern, err: errPermalinkIllFormed}
|
return nil, &permalinkExpandError{pattern: pattern, err: errPermalinkIllFormed}
|
||||||
}
|
}
|
||||||
|
var normalized bool
|
||||||
|
pattern, normalized = l.normalizeEscapeSequencesIn(pattern)
|
||||||
|
|
||||||
matches := attributeRegexp.FindAllStringSubmatch(pattern, -1)
|
matches := attributeRegexp.FindAllStringSubmatch(pattern, -1)
|
||||||
|
if matches == nil {
|
||||||
|
result := pattern
|
||||||
|
if normalized {
|
||||||
|
result = l.normalizeEscapeSequencesOut(result)
|
||||||
|
}
|
||||||
|
return func(p Page) (string, error) {
|
||||||
|
return result, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
callbacks := make([]pageToPermaAttribute, len(matches))
|
callbacks := make([]pageToPermaAttribute, len(matches))
|
||||||
replacements := make([]string, len(matches))
|
replacements := make([]string, len(matches))
|
||||||
for i, m := range matches {
|
for i, m := range matches {
|
||||||
replacement := m[1]
|
replacement := m[0]
|
||||||
attr := replacement[1:]
|
attr := replacement[1:]
|
||||||
replacements[i] = replacement
|
replacements[i] = replacement
|
||||||
callback, ok := l.callback(attr)
|
callback, ok := l.callback(attr)
|
||||||
|
@ -179,10 +189,6 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(p Page) (string, error) {
|
return func(p Page) (string, error) {
|
||||||
if matches == nil {
|
|
||||||
return pattern, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
newField := pattern
|
newField := pattern
|
||||||
|
|
||||||
for i, replacement := range replacements {
|
for i, replacement := range replacements {
|
||||||
|
@ -196,6 +202,10 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
|
||||||
newField = strings.Replace(newField, replacement, newAttr, 1)
|
newField = strings.Replace(newField, replacement, newAttr, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if normalized {
|
||||||
|
newField = l.normalizeEscapeSequencesOut(newField)
|
||||||
|
}
|
||||||
|
|
||||||
return newField, nil
|
return newField, nil
|
||||||
}, nil
|
}, nil
|
||||||
})
|
})
|
||||||
|
@ -222,7 +232,7 @@ func (l PermalinkExpander) parse(patterns map[string]string) (map[string]func(Pa
|
||||||
// can return a string to go in that position in the page (or an error)
|
// can return a string to go in that position in the page (or an error)
|
||||||
type pageToPermaAttribute func(Page, string) (string, error)
|
type pageToPermaAttribute func(Page, string) (string, error)
|
||||||
|
|
||||||
var attributeRegexp = regexp.MustCompile(`(?:^|[^\\])(:\w+(?:\[.+?])?)`)
|
var attributeRegexp = regexp.MustCompile(`:\w+(\[.+?\])?`)
|
||||||
|
|
||||||
// validate determines if a PathPattern is well-formed
|
// validate determines if a PathPattern is well-formed
|
||||||
func (l PermalinkExpander) validate(pp string) bool {
|
func (l PermalinkExpander) validate(pp string) bool {
|
||||||
|
@ -246,7 +256,7 @@ func (l PermalinkExpander) validate(pp string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
k := match[1][1:]
|
k := match[0][1:]
|
||||||
if _, ok := l.callback(k); !ok {
|
if _, ok := l.callback(k); !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,10 @@ func TestPermalinkExpansion(t *testing.T) {
|
||||||
expanded, err := expander.Expand("posts", page)
|
expanded, err := expander.Expand("posts", page)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
c.Assert(expanded, qt.Equals, item.expandsTo)
|
c.Assert(expanded, qt.Equals, item.expandsTo)
|
||||||
|
|
||||||
|
expanded, err = expander.ExpandPattern(item.spec, page)
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(expanded, qt.Equals, item.expandsTo)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue