Installation Add the package via Composer (adapted for Laravel):
composer require didweb/slug
Note: Since this is a Symfony2 bundle, Laravel integration requires manual service registration.
Service Provider Setup
Create a custom service provider (e.g., SlugServiceProvider) in app/Providers/:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Didweb\SlugBundle\Slug\Slug;
class SlugServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('slug', function ($app) {
return new Slug();
});
}
}
Register the provider in config/app.php under providers.
First Use Case Inject the slug service into a controller or use it via the container:
use Illuminate\Support\Facades\Slug;
class PostController extends Controller
{
public function store(Request $request)
{
$title = $request->input('title');
$slug = Slug::clean($title); // Default separator: '-'
// Use $slug in your logic (e.g., save to DB)
}
}
Generating Slugs from User Input Clean and convert dynamic text (e.g., titles, descriptions) into SEO-friendly slugs:
$rawText = "Hello, World! ¿Cómo estás?";
$slug = Slug::clean($rawText); // Output: "hello-world-como-estas"
Custom Separators
Override the default hyphen (-) separator for specific use cases (e.g., underscores for filenames):
$slug = Slug::clean($text, '_'); // Output: "hello_world_como_estas"
Integration with Eloquent Models Use slugs as database columns or routes:
// In a model (e.g., Post.php)
protected static function boot()
{
static::creating(function ($post) {
$post->slug = Str::slug($post->title); // Laravel's Str::slug is similar
});
}
Validation and Sanitization Combine with Laravel’s validation to ensure slugs meet requirements:
$validated = $request->validate([
'title' => 'required|string|max:255',
'slug' => 'nullable|string|max:255|slug', // Custom rule
]);
Route Model Binding Use slugs for clean URLs:
Route::get('/posts/{slug}', [PostController::class, 'show']);
Bind the slug to a model in PostController:
public function show($slug)
{
$post = Post::where('slug', $slug)->firstOrFail();
// ...
}
Namespace Conflicts
The original package uses Didweb\SlugBundle\Slug\Slug, but Laravel’s Str::slug() may shadow expectations. Explicitly use the injected service to avoid ambiguity:
$slug = app('slug')->clean($text); // Force use of the package
Character Encoding Issues
The package handles basic Unicode (e.g., Á, ñ), but edge cases (e.g., CJK characters) may not render as expected. Test with your target locale:
$text = "日本語のテキスト"; // May output: "jp---no---tekisuto" (unintended)
Service Container Binding
If the service isn’t registered, Laravel will throw BindingResolutionException. Verify the provider is loaded and the binding exists:
php artisan package:discover
Performance Overhead
The package is lightweight, but avoid calling clean() in loops or critical paths without benchmarking. Cache results if regenerating slugs frequently:
$slug = cache()->remember("slug_{$title}", now()->addHours(1), function() use ($title) {
return Slug::clean($title);
});
Log Raw vs. Processed Output Debug slug generation by logging intermediate steps:
\Log::debug('Raw text:', [$text]);
\Log::debug('Generated slug:', [Slug::clean($text)]);
Check for Hidden Characters
Use trim() or preg_replace() to strip invisible characters before passing text to the slugger:
$cleanText = preg_replace('/[^\P{C}\s]/u', '', $text); // Remove control chars
$slug = Slug::clean($cleanText);
Custom Cleaning Logic
Extend the Slug class to add pre-processing (e.g., remove stopwords):
namespace App\Services;
use Didweb\SlugBundle\Slug\Slug as BaseSlug;
class CustomSlug extends BaseSlug
{
protected function preClean($text)
{
$stopwords = ['the', 'a', 'an', 'and', 'or'];
return preg_replace('/\b('.implode('|', $stopwords).')\b/i', '', $text);
}
}
Register the custom class in your service provider:
$this->app->singleton('slug', function () {
return new \App\Services\CustomSlug();
});
Post-Processing Hooks Add callbacks for post-cleaning (e.g., enforce length limits):
$slug = Slug::clean($text);
$slug = Str::limit($slug, 50, ''); // Truncate to 50 chars
Laravel Rule Integration Create a reusable validation rule for slugs:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Didweb\SlugBundle\Slug\Slug;
class SlugRule implements Rule
{
public function passes($attribute, $value)
{
return preg_match('/^[a-z0-9_-]+$/i', $value);
}
public function message()
{
return 'The :attribute must be a valid slug.';
}
}
Use it in validation:
$request->validate([
'slug' => ['required', new SlugRule],
]);
How can I help you explore Laravel packages today?