summaryrefslogtreecommitdiffstats
path: root/helpers
diff options
context:
space:
mode:
authorCameron Moore <moorereason@gmail.com>2018-08-22 00:18:37 -0500
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-08-22 07:18:37 +0200
commitfff132537b4094221f4f099e2251f3cda613060f (patch)
tree1b057925f7e8e3e10922aaba2a8e36ef16bc8db2 /helpers
parent8999de193c18b7aa07b44e5b7d9f443a8572e117 (diff)
Fix handling of taxonomy terms containing slashes
Fixes #4090
Diffstat (limited to 'helpers')
-rw-r--r--helpers/path.go29
-rw-r--r--helpers/path_test.go32
2 files changed, 61 insertions, 0 deletions
diff --git a/helpers/path.go b/helpers/path.go
index 3586c5744..7af56960c 100644
--- a/helpers/path.go
+++ b/helpers/path.go
@@ -74,6 +74,35 @@ func (filepathBridge) Separator() string {
var fpb filepathBridge
+// segmentReplacer replaces some URI-reserved characters in a path segments.
+var segmentReplacer = strings.NewReplacer("/", "-", "#", "-")
+
+// MakeSegment returns a copy of string s that is appropriate for a path
+// segment. MakeSegment is similar to MakePath but disallows the '/' and
+// '#' characters because of their reserved meaning in URIs.
+func (p *PathSpec) MakeSegment(s string) string {
+ s = p.MakePathSanitized(strings.Trim(segmentReplacer.Replace(s), "- "))
+
+ var pos int
+ var last byte
+ b := make([]byte, len(s))
+
+ for i := 0; i < len(s); i++ {
+ // consolidate dashes
+ if s[i] == '-' && last == '-' {
+ continue
+ }
+
+ b[pos], last = s[i], s[i]
+ pos++
+ }
+
+ if p.DisablePathToLower {
+ return string(b[:pos])
+ }
+ return strings.ToLower(string(b[:pos]))
+}
+
// MakePath takes a string with any characters and replace it
// so the string could be used in a path.
// It does so by creating a Unicode-sanitized string, with the spaces replaced,
diff --git a/helpers/path_test.go b/helpers/path_test.go
index c249a519d..a97e3d507 100644
--- a/helpers/path_test.go
+++ b/helpers/path_test.go
@@ -36,6 +36,38 @@ import (
"github.com/spf13/viper"
)
+func TestMakeSegment(t *testing.T) {
+ tests := []struct {
+ input string
+ expected string
+ }{
+ {" FOO bar ", "foo-bar"},
+ {"Foo.Bar/fOO_bAr-Foo", "foo.bar-foo_bar-foo"},
+ {"FOO,bar:FooBar", "foobarfoobar"},
+ {"foo/BAR.HTML", "foo-bar.html"},
+ {"трям/трям", "трям-трям"},
+ {"은행", "은행"},
+ {"Say What??", "say-what"},
+ {"Your #1 Fan", "your-1-fan"},
+ {"Red & Blue", "red-blue"},
+ {"double//slash", "double-slash"},
+ {"My // Taxonomy", "my-taxonomy"},
+ }
+
+ for _, test := range tests {
+ v := newTestCfg()
+
+ l := langs.NewDefaultLanguage(v)
+ p, err := NewPathSpec(hugofs.NewMem(v), l)
+ require.NoError(t, err)
+
+ output := p.MakeSegment(test.input)
+ if output != test.expected {
+ t.Errorf("Expected %#v, got %#v\n", test.expected, output)
+ }
+ }
+}
+
func TestMakePath(t *testing.T) {
tests := []struct {
input string