zenstruck/slugify-bundle
Deprecated Symfony2 bundle integrating cocur/slugify. Provides a zenstruck.slugify service and optional Twig slugify filter, with configurable mode (iconv/array) and basic settings for separator and empty-value replacements.
Installation:
composer require zenstruck/slugify-bundle
Enable the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):
Zenstruck\SlugifyBundle\ZenstruckSlugifyBundle::class => ['all' => true],
First Use Case:
Inject the slugify service into a controller or command:
use Cocur\Slugify\Slugify;
class PostController extends AbstractController
{
public function show(Slugify $slugify): Response
{
$title = "My Awesome Post Title";
$slug = $slugify($title); // "my-awesome-post-title"
return $this->render('post/show.html.twig', ['slug' => $slug]);
}
}
Twig Filter:
Use the slugify filter directly in templates:
{{ post.title|slugify }} {# Renders "my-post-title" #}
Generating Slugs for Entities: Use the service in entity listeners or setters:
use Cocur\Slugify\Slugify;
class PostListener
{
public function __construct(private Slugify $slugify) {}
public function prePersist(Post $post): void
{
$post->slug = $this->slugify($post->title);
}
}
Customizing Slug Behavior: Configure the service via DI (Symfony 4+):
# config/services.yaml
services:
Cocur\Slugify\Slugify:
arguments:
$mode: 'array' # or 'iconv'
$separator: '_'
$emptyValue: 'default-slug'
Dynamic Slug Updates:
Trigger slug regeneration on title changes (e.g., via setTitle()):
public function setTitle(string $title): self
{
$this->title = $title;
$this->slug = $this->slugify->slugify($title);
return $this;
}
Twig Extensions: Extend the Twig filter for project-specific rules:
// src/Twig/AppExtension.php
class AppExtension extends AbstractExtension
{
public function getFilters(): array
{
return [
new TwigFilter('custom_slugify', [$this->slugify, 'slugify']),
];
}
}
Deprecation Warning:
The bundle is deprecated in favor of cocur/slugify. Migrate to the standalone library for long-term support:
composer require cocur/slugify
Configuration Overrides:
The mode (array or iconv) affects performance and edge-case handling (e.g., non-ASCII characters). Test both modes if working with multilingual content.
Twig Filter Disabled by Default:
Ensure zenstruck_slugify.twig: true is set in config/packages/zenstruck_slugify.yaml (Symfony 4+) or config.yml (Symfony 2/3) to enable the filter.
Empty Values:
The emptyValue option replaces invalid slugs (e.g., #### → default-slug). Set it explicitly to avoid unexpected behavior:
zenstruck_slugify:
emptyValue: 'n-a'
Invalid Characters:
Use array mode for strict control over replacements:
$slugify->slugify('Café au Lait', '_', 'array');
// Output: "caf__au_lait" (replaces non-alphanumeric chars with `_`)
Performance:
Cache the Slugify service if generating slugs in loops:
# config/services.yaml
services:
Cocur\Slugify\Slugify:
public: false
tags: ['container.cacheable']
Custom Rules:
Extend the Slugify class to add project-specific transformations:
class CustomSlugify extends Slugify
{
protected function transform($str): string
{
$str = parent::transform($str);
return str_replace(['-v', '-ed'], '', $str); // Remove "-v" and "-ed"
}
}
Event-Driven Slugs:
Use Symfony events (e.g., kernel.request) to generate slugs dynamically:
$slug = $this->slugify->slugify($request->get('title'));
$this->addFlash('info', "Slug: {$slug}");
How can I help you explore Laravel packages today?