]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
resources/page: Allow colons in permalinks to be escaped
authorn1xx1 <me@simonemiraglia.it>
Mon, 14 Oct 2024 10:08:31 +0000 (12:08 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 15 Oct 2024 08:28:00 +0000 (10:28 +0200)
Updates #12918

resources/page/permalinks.go
resources/page/permalinks_test.go

index 05911f0eaa638fd8580880008f9ce696eaf567a4..d4b60bb9a281df5b76a9fc1457d8060bd0187640 100644 (file)
@@ -107,6 +107,10 @@ func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]ma
        return p, nil
 }
 
+func (l PermalinkExpander) normalizeEscapeSequences(result string) string {
+       return strings.ReplaceAll(result, "\\:", ":")
+}
+
 // 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)
@@ -114,7 +118,11 @@ func (l PermalinkExpander) ExpandPattern(pattern string, p Page) (string, error)
                return "", err
        }
 
-       return expander(p)
+       result, err := expander(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.
@@ -132,7 +140,11 @@ func (l PermalinkExpander) Expand(key string, p Page) (string, error) {
                return "", nil
        }
 
-       return expand(p)
+       result, err := expand(p)
+       if err != nil {
+               return "", err
+       }
+       return l.normalizeEscapeSequences(result), nil
 }
 
 // Allow " " and / to represent the root section.
@@ -154,7 +166,7 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
                callbacks := make([]pageToPermaAttribute, len(matches))
                replacements := make([]string, len(matches))
                for i, m := range matches {
-                       replacement := m[0]
+                       replacement := m[1]
                        attr := replacement[1:]
                        replacements[i] = replacement
                        callback, ok := l.callback(attr)
@@ -210,7 +222,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)
 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
 func (l PermalinkExpander) validate(pp string) bool {
@@ -234,7 +246,7 @@ func (l PermalinkExpander) validate(pp string) bool {
                }
 
                for _, match := range matches {
-                       k := match[0][1:]
+                       k := match[1][1:]
                        if _, ok := l.callback(k); !ok {
                                return false
                        }
index a3a45bb88754fe995bbb525c4d6bec3f7cbb67af..9a8ac51f2981280fa1f6471ffd17218d8f53f911 100644 (file)
@@ -44,6 +44,8 @@ var testdataPermalinks = []struct {
        {"/:sections/", true, "/a/b/c/"},                                // Sections
        {"/:sections[last]/", true, "/c/"},                              // Sections
        {"/:sections[0]/:sections[last]/", true, "/a/c/"},               // Sections
+       {"/\\:filename", true, "/:filename"},                            // Escape sequence
+       {"/special\\::slug/", true, "/special:the-slug/"},               // Escape sequence
 
        // Failures
        {"/blog/:fred", false, ""},
@@ -117,6 +119,7 @@ func TestPermalinkExpansionMultiSection(t *testing.T) {
                        "posts":   "/:slug",
                        "blog":    "/:section/:year",
                        "recipes": "/:slugorfilename",
+                       "special": "/special\\::slug",
                },
        }
        expander, err := NewPermalinkExpander(urlize, permalinksConfig)
@@ -137,6 +140,10 @@ func TestPermalinkExpansionMultiSection(t *testing.T) {
        expanded, err = expander.Expand("recipes", page_slug_fallback)
        c.Assert(err, qt.IsNil)
        c.Assert(expanded, qt.Equals, "/page-filename")
+
+       expanded, err = expander.Expand("special", page)
+       c.Assert(err, qt.IsNil)
+       c.Assert(expanded, qt.Equals, "/special:the-slug")
 }
 
 func TestPermalinkExpansionConcurrent(t *testing.T) {