diff options
author | Cameron Moore <moorereason@gmail.com> | 2018-08-22 00:18:37 -0500 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2018-08-22 07:18:37 +0200 |
commit | fff132537b4094221f4f099e2251f3cda613060f (patch) | |
tree | 1b057925f7e8e3e10922aaba2a8e36ef16bc8db2 /helpers | |
parent | 8999de193c18b7aa07b44e5b7d9f443a8572e117 (diff) |
Fix handling of taxonomy terms containing slashes
Fixes #4090
Diffstat (limited to 'helpers')
-rw-r--r-- | helpers/path.go | 29 | ||||
-rw-r--r-- | helpers/path_test.go | 32 |
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 |