philiprehberger-slug
URL-friendly slug generator with Unicode transliteration and collision-aware uniqueness
Requirements
- Ruby >= 3.1
Installation
Add to your Gemfile:
gem "philiprehberger-slug"
Or install directly:
gem install philiprehberger-slug
Usage
require "philiprehberger/slug"
Philiprehberger::Slug.generate("Hello World!") # => "hello-world"
Philiprehberger::Slug.generate("Héllo Wörld") # => "hello-world"
Philiprehberger::Slug.generate("Привет мир") # => "privet-mir"
Custom Separator
Philiprehberger::Slug.generate("Hello World", separator: "_") # => "hello_world"
Max Length
Truncates at the nearest word boundary:
Philiprehberger::Slug.generate("Hello Beautiful World", max: 16) # => "hello-beautiful"
Uniqueness
Pass a callable that returns true if the slug already exists:
Philiprehberger::Slug.generate("My Post", unique: ->(s) { Post.exists?(slug: s) })
# => "my-post" or "my-post-2" if "my-post" exists
Batch Generation
Generate unique slugs for multiple strings with automatic deduplication:
Philiprehberger::Slug.generate_batch(%w[Hello Hello Hello])
# => ["hello", "hello-2", "hello-3"]
Philiprehberger::Slug.generate_batch(["My Post", "Another Post", "My Post"])
# => ["my-post", "another-post", "my-post-2"]
Custom Character Mapping
Override or extend the default transliteration with custom character replacements:
Philiprehberger::Slug.generate("Hello & World", custom_mapping: { "&" => "and" })
# => "hello-and-world"
Validation
Check whether a string is already a well-formed slug:
Philiprehberger::Slug.valid_slug?("hello-world") # => true
Philiprehberger::Slug.valid_slug?("Hello World") # => false
Philiprehberger::Slug.valid_slug?("hello--world") # => false
Humanize
Convert a slug back to a human-readable title:
Philiprehberger::Slug.humanize("hello-world") # => "Hello World"
Philiprehberger::Slug.humanize("hello-world", capitalize: :first) # => "Hello world"
Philiprehberger::Slug.humanize("hello_world", separator: "_") # => "Hello World"
Transliteration
Philiprehberger::Slug.transliterate("café résumé") # => "cafe resume"
Rails-compatible Alias
For callers familiar with ActiveSupport::Inflector#parameterize:
Philiprehberger::Slug.parameterize("Hello World!") # => "hello-world"
API
| Method | Description |
|---|---|
Slug.generate(string, separator:, max:, unique:, custom_mapping:) |
Generate a URL-safe slug from any string |
Slug.parameterize(string, separator:, max:, custom_mapping:) |
Rails-compatible alias for generate |
Slug.generate_batch(strings, separator:, max:, custom_mapping:) |
Generate unique slugs for an array of strings with deduplication |
Slug.valid_slug?(string, separator:) |
Check whether a string is a well-formed slug |
Slug.humanize(slug, separator:, capitalize:) |
Convert a slug back to a human-readable title |
Slug.transliterate(string, custom_mapping:) |
Transliterate Unicode characters to ASCII equivalents |
Slug::Error |
Error raised for invalid input (e.g. non-String argument) |
Slug::VERSION |
Current gem version string |
Development
bundle install
bundle exec rspec
bundle exec rubocop
Support
If you find this project useful: