Skip to content

Commit

Permalink
Add AppendTimestamp option to make slug unique
Browse files Browse the repository at this point in the history
  • Loading branch information
phihungtf authored and matrixik committed Feb 23, 2024
1 parent 4a8e359 commit 6b0799c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
15 changes: 15 additions & 0 deletions slug.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
"bytes"
"regexp"
"sort"
"strconv"
"strings"
"time"

"github.com/gosimple/unidecode"
)
Expand All @@ -36,6 +38,10 @@ var (
// Default is true.
Lowercase = true

// Append timestamp to the end in order to make slug unique
// Default is false
AppendTimestamp = false

regexpNonAuthorizedChars = regexp.MustCompile("[^a-zA-Z0-9-_]")
regexpMultipleDashes = regexp.MustCompile("-+")
)
Expand Down Expand Up @@ -127,6 +133,10 @@ func MakeLang(s string, lang string) (slug string) {
slug = smartTruncate(slug)
}

if AppendTimestamp {
slug = slug + "-" + timestamp()
}

return slug
}

Expand Down Expand Up @@ -177,6 +187,11 @@ func smartTruncate(text string) string {
return text[:MaxLength]
}

// timestamp returns current timestamp as string
func timestamp() string {
return strconv.FormatInt(time.Now().Unix(), 10)
}

// IsSlug returns True if provided text does not contain white characters,
// punctuation, all letters are lower case and only from ASCII range.
// It could contain `-` and `_` but not at the beginning or end of the text.
Expand Down
80 changes: 80 additions & 0 deletions slug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package slug

import (
"regexp"
"testing"
)

Expand Down Expand Up @@ -344,6 +345,85 @@ func TestSlugMakeSmartTruncate(t *testing.T) {
}
}

func TestSlugMakeAppendTimestamp(t *testing.T) {
testCases := []struct {
in string
want string
appendTimestamp bool
}{
{"DOBROSLAWZYBORT", "dobroslawzybort", true},
{"Dobroslaw Zybort", "dobroslaw-zybort", true},
{" Dobroslaw Zybort ?", "dobroslaw-zybort", true},
{"Dobrosław Żybort", "dobroslaw-zybort", true},
{"Ala ma 6 kotów.", "ala-ma-6-kotow", true},

{"áÁàÀãÃâÂäÄąĄą̊Ą̊", "aaaaaaaaaaaaaa", true},
{"ćĆĉĈçÇčČ", "cccccccc", true},
{"éÉèÈẽẼêÊëËęĘěĚ", "eeeeeeeeeeeeee", true},
{"íÍìÌĩĨîÎïÏįĮ", "iiiiiiiiiiii", true},
{"łŁ", "ll", true},
{"ńŃ", "nn", true},
{"óÓòÒõÕôÔöÖǫǪǭǬø", "ooooooooooooooo", true},
{"śŚšŠ", "ssss", true},
{"řŘ", "rr", true},
{"ťŤ", "tt", true},
{"úÚùÙũŨûÛüÜųŲůŮ", "uuuuuuuuuuuuuu", true},
{"y̨Y̨ýÝ", "yyyy", true},
{"źŹżŹžŽ", "zzzzzz", true},
{"·/,:;`˜'\"", "", true},
{"2000–2013", "2000-2013", true},
{"style—not", "style-not", true},
{"test_slug", "test_slug", true},
{"_test_slug_", "test_slug", true},
{"-test-slug-", "test-slug", true},
{"Æ", "ae", true},
{"Ich heiße", "ich-heisse", true},
{"𐀀", "", true}, // Bug #53
{"% 5 @ 4 $ 3 / 2 & 1 & 2 # 3 @ 4 _ 5", "5-at-4-3-2-and-1-and-2-3-at-4-_-5", true},

{"This & that", "this-and-that", true},
{"fácil €", "facil-eu", true},
{"smile ☺", "smile", true},
{"Hellö Wörld хелло ворлд", "hello-world-khello-vorld", true},
{"\"C'est déjà l’été.\"", "cest-deja-lete", true},
{"jaja---lol-méméméoo--a", "jaja-lol-mememeoo-a", true},
{"影師", "ying-shi", true},
{"Đanković & Kožušček", "dankovic-and-kozuscek", true},
{"ĂăÂâÎîȘșȚț", "aaaaiisstt", true},

// No append timestamp
{"DOBROSLAWZYBORT", "dobroslawzybort", false},
{"Dobroslaw Zybort", "dobroslaw-zybort", false},
{" Dobroslaw Zybort ?", "dobroslaw-zybort", false},
{"Dobrosław Żybort", "dobroslaw-zybort", false},
{"Ala ma 6 kotów.", "ala-ma-6-kotow", false},
}

for index, st := range testCases {
if st.appendTimestamp {
AppendTimestamp = true
} else {
AppendTimestamp = false
}
got := Make(st.in)
if st.appendTimestamp {
want := regexp.MustCompile(`^` + st.want + `-\d{10}$`)
if !want.MatchString(got) {
t.Errorf(
"%d. AppendTimestamp = %v; Make(%#v) = %#v; want %#v",
index, st.appendTimestamp, st.in, got, want,
)
}
continue
}
if got != st.want {
t.Errorf(
"%d. Make(%#v) = %#v; want %#v",
index, st.in, got, st.want)
}
}
}

func TestIsSlug(t *testing.T) {
MaxLength = 0
type args struct {
Expand Down

0 comments on commit 6b0799c

Please sign in to comment.