Skip to main content

A lightweight Python library for converting text to URL-friendly slugs with full Unicode support and zero dependencies

Project description

Smart Slugify

A lightweight (0 dependency), smart Python library for converting text into URL-friendly slugs with Unicode support, accent normalization, and customizable options.

CI PyPI version Python Version License: MIT

Features

Smart Text Normalization: Automatically handles Unicode characters and removes diacritics
🌍 International Support: Works seamlessly with non-ASCII characters (Chinese, Arabic, Cyrillic, etc.)
⚙️ Customizable: Configure separator, casing, and maximum length
🚀 Fast & Lightweight: No external dependencies, pure Python
🧪 Well-Tested: Comprehensive test suite included

Installation

Using pip

pip install smart-slugify

From Source

git clone https://github.com/ali-hai-der/smart-slugify.git
cd smart-slugify
pip install -e .

Quick Start

from smart_slugify import slugify

# Basic usage
slugify("Hello World!")
# Output: 'hello-world'

# Handles Unicode and accents automatically
slugify("C'est déjà l'été!")
# Output: 'c-est-deja-l-ete'

Usage Examples

Basic Text Conversion

from smart_slugify import slugify

# Simple text
slugify("Hello World!")
# 'hello-world'

# Multiple spaces and special characters
slugify("Hello   World!!! How are you?")
# 'hello-world-how-are-you'

# Numbers are preserved
slugify("Python 3.11 Released!")
# 'python-3-11-released'

Unicode and Accent Handling

Smart Slugify automatically normalizes Unicode characters and removes diacritics:

# French
slugify("C'est déjà l'été!")
# 'c-est-deja-l-ete'

# Spanish
slugify("¿Cómo estás?")
# 'como-estas'

# Portuguese
slugify("São Paulo")
# 'sao-paulo'

# German
slugify("Über uns")
# 'uber-uns'

# Mixed content
slugify("Café au lait & crème brûlée")
# 'cafe-au-lait-creme-brulee'

Custom Separators

Change the default separator from hyphen to any character:

# Underscore separator
slugify("Hello World!", separator="_")
# 'hello_world'

# Dot separator
slugify("My Blog Post", separator=".")
# 'my.blog.post'

# No separator (empty string)
slugify("Hello World", separator="")
# 'helloworld'

Case Sensitivity

Control whether the output should be lowercase:

# Default: lowercase
slugify("Hello World")
# 'hello-world'

# Preserve original case
slugify("Hello World", lowercase=False)
# 'Hello-World'

# Mixed case with underscores
slugify("iPhone 15 Pro", lowercase=False, separator="_")
# 'iPhone_15_Pro'

Maximum Length

Truncate slugs to a specific length:

# Truncate at 10 characters
slugify("hello world example", max_length=10)
# 'hello-wor'

# Smart truncation removes trailing separators
slugify("hello-world-test", max_length=12)
# 'hello-world'  (not 'hello-world-')

# Long URLs
slugify("This is a very long article title that needs to be shortened", max_length=30)
# 'this-is-a-very-long-article-t'

Edge Cases

Smart Slugify handles edge cases gracefully:

# Empty string
slugify("")
# ''

# None input
slugify(None)
# ''

# Only special characters
slugify("!!@@##$$")
# ''

# Leading/trailing spaces and separators
slugify("  Hello World  ")
# 'hello-world'

Real-World Examples

# Blog post URL
title = "10 Tips for Better Python Code in 2024"
slug = slugify(title)
# '10-tips-for-better-python-code-in-2024'
url = f"https://myblog.com/posts/{slug}"

# Product slugs for e-commerce
product = "MacBook Pro 16\" (2024) - Space Gray"
product_slug = slugify(product)
# 'macbook-pro-16-2024-space-gray'

# User-friendly file names
filename = "My Résumé - Software Engineer.pdf"
safe_filename = slugify(filename, separator="_")
# 'my_resume_software_engineer_pdf'

# Category paths
category = "Fashion & Accessories / Women's Clothing"
category_path = slugify(category, separator="/")
# 'fashion-accessories/women-s-clothing'

API Reference

slugify(text, lowercase=True, separator='-', max_length=None)

Converts input text into a URL-friendly slug.

Parameters:

  • text (str): The input text to slugify. Can be None (returns empty string).
  • lowercase (bool, optional): Convert to lowercase. Default: True.
  • separator (str, optional): Character to use as separator. Default: '-'.
  • max_length (int, optional): Maximum length of the slug. Default: None (no limit).

Returns:

  • str: The slugified text.

Processing Steps:

  1. Normalizes Unicode to NFKD form
  2. Removes diacritical marks (accents)
  3. Converts to lowercase (if enabled)
  4. Replaces non-alphanumeric characters with separator
  5. Collapses multiple consecutive separators into one
  6. Strips leading and trailing separators
  7. Truncates to max_length (if specified)
  8. Removes trailing separators after truncation

Development

Running Tests

# Install pytest if you haven't already
pip install pytest

# Run tests
pytest tests/

# Run with verbose output
pytest -v tests/

# Run with coverage
pip install pytest-cov
pytest --cov=smart_slugify tests/

Project Structure

smart-slugify/
├── src/
│   └── smart_slugify/
│       ├── __init__.py
│       └── slugify.py
├── tests/
│   └── test_slugify.py
├── pyproject.toml
├── README.md
└── LICENSE

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please make sure to:

  • Add tests for new features
  • Update documentation as needed
  • Follow PEP 8 style guidelines
  • Write clear commit messages

Use Cases

  • Web Applications: Generate SEO-friendly URLs for blog posts, articles, and pages
  • E-commerce: Create readable product URLs
  • CMS Systems: Auto-generate slugs from user-provided titles
  • File Management: Convert file names to safe, filesystem-friendly names
  • APIs: Create consistent, readable endpoint identifiers
  • Database Keys: Generate human-readable unique identifiers

Why Smart Slugify?

  • No Dependencies: Pure Python implementation with no external packages
  • Unicode-First: Properly handles international characters out of the box
  • Battle-Tested: Based on best practices from popular slugify implementations
  • Flexible: Customizable to fit your specific needs
  • Lightweight: Minimal footprint, fast performance

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Haider Ali
Email: malikhaider0567@gmail.com

Acknowledgments

  • Inspired by Django's slugify utility
  • Unicode normalization based on Python's unicodedata module

Changelog

Version 0.1.0 (Initial Release)

  • Basic slugification with Unicode support
  • Configurable separator and casing
  • Maximum length truncation
  • Comprehensive test suite

Star ⭐ this repository if you find it useful!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smart_slugify-0.1.2.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smart_slugify-0.1.2-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file smart_slugify-0.1.2.tar.gz.

File metadata

  • Download URL: smart_slugify-0.1.2.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for smart_slugify-0.1.2.tar.gz
Algorithm Hash digest
SHA256 94e4c73ad617e0ab77210020ddda32696ddb1fe4c513d8f70645898688816207
MD5 c1afff5e445576c4bdf109ec9f27c2e0
BLAKE2b-256 969cdbde4360a71015adab865bcc1ccffbdc2c73812e4d1f7c70444294305349

See more details on using hashes here.

File details

Details for the file smart_slugify-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: smart_slugify-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for smart_slugify-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d7fca1778238a5235dadd345ef0b81dd2c8cf70a6c2d578589c7625d8f5d5dee
MD5 6efc84195515d3516747b6ea7dd1ae27
BLAKE2b-256 b1e5b94e637ddb7a0da174f750aa821e275b2b0ce55fd768f75d57588be7c5fc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page