-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add option to automatically generate slug from another field (#258)
* Allow automatically generating a slug from another field * Fix test description * Add encoding param to MySQL/MariDB config * Add testcase * Fix findings * Remove callback doc * Fix base validation * Fix findings * Fix sluggable tests * Allow unicode * Update fields.md * Update base.cr
- Loading branch information
Showing
11 changed files
with
271 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
require "./spec_helper" | ||
|
||
describe Marten::Core::Sluggable do | ||
describe "#generate_slug" do | ||
value = "Test Title 12354543435" | ||
max_size = 20 | ||
g_slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(value, max_size) | ||
|
||
it "removes non-alphanumeric characters" do | ||
value_with_special_chars = "Test@Title#123!" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(value_with_special_chars, max_size) | ||
slug.should eq("testtitle123") | ||
end | ||
|
||
it "handles emojis" do | ||
value_with_emojis = "🚀 TRAVEL & PLACES" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(value_with_emojis, max_size) | ||
slug.should eq("🚀-travel-places") | ||
end | ||
it "converts the string to lowercase" do | ||
g_slug.should eq("test-title-123545434") | ||
end | ||
|
||
it "replaces whitespace and hyphens with a single hyphen" do | ||
value_with_spaces_and_hyphens = "Test - Title 123" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(value_with_spaces_and_hyphens, max_size) | ||
slug.should eq("test-title-123") | ||
end | ||
|
||
it "strips leading and trailing hyphens and underscores" do | ||
value_with_hyphens = "-Test Title 123-" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(value_with_hyphens, max_size) | ||
slug.should eq("test-title-123") | ||
end | ||
|
||
it "removes non-ASCII characters" do | ||
value_with_non_ascii = "Test Títle 123" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(value_with_non_ascii, max_size) | ||
slug.should eq("test-títle-123") | ||
end | ||
|
||
it "limits the slug length to max_size" do | ||
g_slug.size.should eq(max_size) | ||
end | ||
|
||
it "does not exceed max_size even with long input" do | ||
long_value = "This is a very long title that should be truncated" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(long_value, max_size) | ||
slug.size.should be <= max_size | ||
end | ||
|
||
it "does not truncate the slug when max_size is large enough" do | ||
long_value = "This is a very long title that should not be truncated" | ||
slug = Marten::Core::SluggableSpec::SlugGenerator.new.generate_slug(long_value, 100) | ||
|
||
slug.should eq("this-is-a-very-long-title-that-should-not-be-truncated") | ||
end | ||
end | ||
end | ||
|
||
module Marten::Core::SluggableSpec | ||
class SlugGenerator | ||
include Marten::Core::Sluggable | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
require "./models/**" | ||
|
||
class Marten::DB::Field::SlugSpec::App < Marten::App | ||
label :marten_db_field_slug_spec | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module Marten::DB::Field::SlugSpec | ||
class Article < Marten::Model | ||
field :id, :big_int, primary_key: true, auto: true | ||
field :title, :string, max_size: 255 | ||
field :slug, :slug, slugify: :title | ||
end | ||
end |
7 changes: 7 additions & 0 deletions
7
spec/marten/db/field/slug_spec/models/article_invalid_slug_field.cr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module Marten::DB::Field::SlugSpec | ||
class ArticleInvalidSlugField < Marten::Model | ||
field :id, :big_int, primary_key: true, auto: true | ||
field :title, :string, max_size: 255 | ||
field :slug, :slug, slugify: :invalid, max_size: 100 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module Marten::DB::Field::SlugSpec | ||
class ArticleLongSlug < Marten::Model | ||
field :id, :big_int, primary_key: true, auto: true | ||
field :title, :string, max_size: 255 | ||
field :slug, :slug, slugify: :title, max_size: 100 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module Marten | ||
module Core | ||
# The Sluggable module provides functionality for generating URL-friendly slugs from strings. | ||
module Sluggable | ||
private NON_ALPHANUMERIC_RE = /[^\p{L}\p{N}\p{So}\s-]/ | ||
private WHITESPACE_HYPHEN_RE = /[-\s]+/ | ||
|
||
# Generates a slug from the given value, ensuring the resulting slug does not exceed the specified max_size. | ||
# | ||
# The slug is created by: | ||
# 1. Removing non-alphanumeric characters (except for Unicode letters, numbers, symbols, whitespace, and hyphens). | ||
# 2. Converting the string to lowercase. | ||
# 3. Replacing sequences of whitespace and hyphens with a single hyphen. | ||
# 4. Stripping trailing hyphens and underscores from the slug. | ||
# 5. Truncating the slug to the specified max_size. | ||
def generate_slug(value, max_size) | ||
slug = value.gsub(NON_ALPHANUMERIC_RE, "").downcase | ||
slug = slug.gsub(WHITESPACE_HYPHEN_RE, "-") | ||
slug[...(max_size)].strip("-_") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters