Slugification¶
translit generates URL-safe slugs from Unicode text. The slugify() function is parameter-compatible with python-slugify, so migration requires only changing the import.
Basic usage¶
from translit import slugify
slugify("Hello, World!") # => "hello-world"
slugify("My Blog Post — Draft #3") # => "my-blog-post-draft-3"
slugify("Ünïcödé Téxt") # => "unicode-text"
Parameters¶
separator¶
The character used between words (default: "-"):
slugify("hello world", separator="_") # => "hello_world"
slugify("hello world", separator=".") # => "hello.world"
lowercase¶
Whether to lowercase the output (default: True):
slugify("Hello World", lowercase=False) # => "Hello-World"
max_length¶
Truncate the slug to a maximum length (default: 0 = unlimited):
slugify("a very long title here", max_length=10)
# => "a-very-lon"
word_boundary¶
When combined with max_length, truncate at word boundaries:
slugify("a very long title here", max_length=10, word_boundary=True)
# => "a-very"
stopwords¶
Words to remove from the slug:
slugify("the quick brown fox", stopwords=["the", "brown"])
# => "quick-fox"
regex_pattern¶
Custom regex pattern for allowed characters:
slugify("hello 123 world", regex_pattern=r"[^a-z]+")
# => "helloworld"
replacements¶
Pre-transliteration string replacements:
slugify("C++ Programming", replacements=[("C++", "cpp")])
# => "cpp-programming"
allow_unicode¶
Keep non-ASCII characters in the slug:
slugify("日本語テスト", allow_unicode=True)
# => "日本語テスト"
lang¶
Language profile for transliteration:
slugify("Ärger im Büro", lang="de")
# => "aerger-im-buero"
Use lang="auto" to auto-detect the language from the script:
slugify("Москва", lang="auto") # => "moskva" (detects Cyrillic → Russian)
slugify("ภาษาไทย", lang="auto") # => Thai slug (detects Thai)
entities, decimal, hexadecimal¶
Decode HTML entities and numeric character references:
slugify("& test &") # => "test"
Reusable slugifiers¶
Slugifier¶
Pre-configure a slugifier for repeated use:
from translit import Slugifier
slug = Slugifier(separator="_", lang="de", max_length=50)
slug("Ärger im Büro") # => "aerger_im_buero"
slug("Über den Wolken") # => "ueber_den_wolken"
UniqueSlugifier¶
Track previously generated slugs and append numeric suffixes for uniqueness:
from translit import UniqueSlugifier
unique = UniqueSlugifier()
unique("My Post") # => "my-post"
unique("My Post") # => "my-post-1"
unique("My Post") # => "my-post-2"
unique.reset() # clear history
unique("My Post") # => "my-post"
External uniqueness check¶
Pass a callback for database-backed uniqueness:
def check_db(slug: str) -> bool:
"""Return True if slug already exists."""
return db.slugs.exists(slug)
unique = UniqueSlugifier(check=check_db)
unique("My Post") # queries check_db before returning
Full pipeline¶
The slugification pipeline executes in this order:
- Apply
replacements - Decode HTML entities (if
entities=True) - Decode decimal references (if
decimal=True) - Decode hexadecimal references (if
hexadecimal=True) - Transliterate (using
langif set), or keep Unicode (ifallow_unicode=True) - Lowercase (if
lowercase=True) - Apply
regex_pattern - Replace non-alphanumeric with
separator - Collapse consecutive separators
- Remove
stopwords - Truncate to
max_length(respectingword_boundaryandsave_order) - Strip leading/trailing separators