philiprehberger-slug

Tests Gem Version Last updated

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:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT