Add unicode support for aliases, indexes, urlize template filter.

Now aliases and indexes are not restricted ASCII letters and can include
any unicode letters.
This commit is contained in:
Anton Ageev 2014-02-02 18:18:01 +04:00
parent 72ba6d633d
commit 9af40c1b52
5 changed files with 77 additions and 4 deletions

View file

@ -14,16 +14,43 @@
package helpers package helpers
import ( import (
"net/url"
"regexp" "regexp"
"strings" "strings"
"unicode"
) )
var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]") var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]")
func Urlize(url string) string { func MakePath(s string) string {
return Sanitize(strings.ToLower(strings.Replace(strings.TrimSpace(url), " ", "-", -1))) return unicodeSanitize(strings.ToLower(strings.Replace(strings.TrimSpace(s), " ", "-", -1)))
}
func Urlize(uri string) string {
sanitized := MakePath(uri)
// escape unicode letters
parsedUri, err := url.Parse(sanitized)
if err != nil {
// if net/url can not parse URL it's meaning Sanitize works incorrect
panic(err)
}
return parsedUri.String()
} }
func Sanitize(s string) string { func Sanitize(s string) string {
return sanitizeRegexp.ReplaceAllString(s, "") return sanitizeRegexp.ReplaceAllString(s, "")
} }
func unicodeSanitize(s string) string {
source := []rune(s)
target := make([]rune, 0, len(source))
for _, r := range source {
if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '.' || r == '/' || r == '_' || r == '-' {
target = append(target, r)
}
}
return string(target)
}

45
helpers/templates_test.go Normal file
View file

@ -0,0 +1,45 @@
package helpers
import (
"testing"
)
func TestMakePath(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:foo%bar", "foobarfoobar"},
{"foo/bar.html", "foo/bar.html"},
{"трям/трям", "трям/трям"},
}
for _, test := range tests {
output := MakePath(test.input)
if output != test.expected {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
}
}
}
func TestUrlize(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:foo%bar", "foobarfoobar"},
{"foo/bar.html", "foo/bar.html"},
{"трям/трям", "%D1%82%D1%80%D1%8F%D0%BC/%D1%82%D1%80%D1%8F%D0%BC"},
}
for _, test := range tests {
output := Urlize(test.input)
if output != test.expected {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
}
}
}

View file

@ -59,7 +59,7 @@ type OrderedIndexEntry struct {
// KeyPrep... Indexes should be case insensitive. Can make it easily conditional later. // KeyPrep... Indexes should be case insensitive. Can make it easily conditional later.
func kp(in string) string { func kp(in string) string {
return helpers.Urlize(in) return helpers.MakePath(in)
} }
func (i Index) Get(key string) WeightedPages { return i[kp(key)] } func (i Index) Get(key string) WeightedPages { return i[kp(key)] }

View file

@ -20,6 +20,7 @@ func TestHTMLRedirectAlias(t *testing.T) {
{"alias 3.html", "alias-3.html"}, {"alias 3.html", "alias-3.html"},
{"alias4.html", "alias4.html"}, {"alias4.html", "alias4.html"},
{"/alias 5.html", "/alias-5.html"}, {"/alias 5.html", "/alias-5.html"},
{"/трям.html", "/трям.html"},
} }
for _, test := range tests { for _, test := range tests {

View file

@ -39,7 +39,7 @@ func (h *HTMLRedirectAlias) Translate(alias string) (aliasPath string, err error
} else if !strings.HasSuffix(alias, ".html") { } else if !strings.HasSuffix(alias, ".html") {
alias = alias + "/index.html" alias = alias + "/index.html"
} }
return path.Join(h.PublishDir, helpers.Urlize(alias)), nil return path.Join(h.PublishDir, helpers.MakePath(alias)), nil
} }
type AliasNode struct { type AliasNode struct {