Skip to content

Commit

Permalink
helpers: Add PathSpec.MakePathSegment
Browse files Browse the repository at this point in the history
MakePathSegment properly sanitizes path segments (like taxonomy terms) with
slashes (and pound signs).

Updates gohugoio#4090
  • Loading branch information
moorereason committed Aug 21, 2018
1 parent 56a8aa1 commit 574d7a8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
29 changes: 29 additions & 0 deletions helpers/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
28 changes: 28 additions & 0 deletions helpers/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ import (
"github.com/spf13/viper"
)

func TestMakeSegment(t *testing.T) {
v := viper.New()
l := NewDefaultLanguage(v)
p, _ := NewPathSpec(hugofs.NewMem(v), l)

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"},
}

for _, test := range tests {
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
Expand Down

0 comments on commit 574d7a8

Please sign in to comment.