slug-utils 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +65 -2
- data/lib/slug_utils/version.rb +1 -1
- data/lib/slug_utils.rb +25 -7
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 62a5e2b648dfaf2b1724a7ee5dfe8ff5e5d7eec92752770d4c87064ea586fd1e
|
|
4
|
+
data.tar.gz: 1eeaf7f6181829aa0c67eca595c77d2af5923fe37b8f0e2845d1fb2ce829fe33
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09a41ec1288a1eb129cbca449d0bc624c50b681df784985b08370acc0602dd2c6f498adb539578b4ed6828ed61030244ac2273f31fa9b78347924808778a4845'
|
|
7
|
+
data.tar.gz: 3a9f648dd2d1c96cabef938507599b977dab54825d3aff8f35c98b5af84ae35d7dc3a503ecb21369c662d1730f952b0a9c1c7a6217609c2ac2aabfc246aa024c
|
data/README.md
CHANGED
|
@@ -1,16 +1,79 @@
|
|
|
1
1
|
# SlugUtils
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`SlugUtils` is a Ruby module for generating clean, SEO-friendly slugs from multi-language text (Vietnamese, Japanese, Chinese, etc.).
|
|
4
|
+
It also provides a method to generate **unique slugs** to avoid duplicates.
|
|
5
|
+
|
|
6
|
+
---
|
|
4
7
|
|
|
5
8
|
## Installation
|
|
6
9
|
|
|
10
|
+
Add the gem via Git:
|
|
11
|
+
|
|
7
12
|
```ruby
|
|
8
|
-
gem "slug-utils",
|
|
13
|
+
gem "slug-utils", ~> "0.1.1"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then run:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bundle install
|
|
9
20
|
```
|
|
21
|
+
---
|
|
10
22
|
|
|
11
23
|
## Usage
|
|
12
24
|
|
|
25
|
+
### Generate basic slug
|
|
26
|
+
|
|
27
|
+
**Default ASCII** (Latin only, accents removed):
|
|
28
|
+
|
|
13
29
|
```ruby
|
|
14
30
|
SlugUtils.generate("Học Ruby on Rails 2025!")
|
|
15
31
|
# => "hoc-ruby-on-rails-2025"
|
|
16
32
|
```
|
|
33
|
+
|
|
34
|
+
**Multi-language with Unicode** (keep accents):
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
SlugUtils.generate("Bài viết mới 新しい記事", keep_accents: true)
|
|
38
|
+
# => "bài-viết-mới-新しい記事"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Multi-language ASCII** (kanji/kana removed):
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
SlugUtils.generate("Bài viết mới 新しい記事")
|
|
45
|
+
# => "bai-viet-moi"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
### Generate unique slug
|
|
51
|
+
|
|
52
|
+
Automatically append `-1`, `-2`, … if the slug already exists:
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
SlugUtils.generate_unique("Bài viết mới", existing: ["bai-viet-moi", "bai-viet-moi-1"])
|
|
56
|
+
# => "bai-viet-moi-2"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### Handling invalid input
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
SlugUtils.generate(nil)
|
|
65
|
+
# => raise SlugUtils::InvalidText
|
|
66
|
+
|
|
67
|
+
SlugUtils.generate(" ")
|
|
68
|
+
# => raise SlugUtils::InvalidText
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### Notes
|
|
74
|
+
|
|
75
|
+
* `keep_accents: true` → preserves all Unicode characters, including Latin letters with accents, kana, kanji, Chinese, Korean, etc.
|
|
76
|
+
* `keep_accents: false` → ASCII-friendly, only converts Latin letters (kana/kanji are removed if no external gem is used)
|
|
77
|
+
* `generate_unique` ensures the slug is unique when saving to the database or an array
|
|
78
|
+
|
|
79
|
+
---
|
data/lib/slug_utils/version.rb
CHANGED
data/lib/slug_utils.rb
CHANGED
|
@@ -6,14 +6,32 @@ module SlugUtils
|
|
|
6
6
|
class Error < StandardError; end
|
|
7
7
|
class InvalidText < Error; end
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
def self.generate(text)
|
|
9
|
+
def self.generate(text, keep_accents: false)
|
|
11
10
|
raise InvalidText, "Text cannot be blank" if text.nil? || text.strip.empty?
|
|
12
11
|
|
|
13
|
-
text.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
slug = text.strip.downcase
|
|
13
|
+
|
|
14
|
+
if keep_accents
|
|
15
|
+
slug.gsub!(/[^\p{L}\p{N}]+/u, "-")
|
|
16
|
+
else
|
|
17
|
+
slug = slug.unicode_normalize(:nfkd).encode("ASCII", replace: "")
|
|
18
|
+
slug.gsub!(/[^a-z0-9]+/, "-")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
slug.gsub!(/^-+|-+$/, "")
|
|
22
|
+
slug
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.generate_unique(text, existing: [], keep_accents: false)
|
|
26
|
+
base_slug = generate(text, keep_accents:)
|
|
27
|
+
slug = base_slug
|
|
28
|
+
counter = 1
|
|
29
|
+
|
|
30
|
+
while existing.include?(slug)
|
|
31
|
+
slug = "#{base_slug}-#{counter}"
|
|
32
|
+
counter += 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
slug
|
|
18
36
|
end
|
|
19
37
|
end
|