Laravel Sluggable
Nuno Maduro 发布了 Laravel Sluggable,这是一个用于在 Eloquent 模型上自动生成缩略名(slug)的包。该包不依赖于 trait 或基类,而是直接在模型上使用一个 PHP 注解 #[Sluggable]。
除了基础知识外,它还涵盖了在实际应用中可能出现的边缘情况:碰撞处理、作用域唯一性(每个租户、每个语言环境)、多列源、软删除记录碰撞,以及完整的 Unicode 和 CJK 音译。
开始
Composer 安装
composer require nunomaduro/laravel-sluggable注意:此包需要 PHP 8.5+ 和 Laravel 13.5+
配置模型的最快方法是通过内置的 make:sluggable Artisan 命令:
php artisan make:sluggable Post它会读取你的模型的表结构,选择最可能的源列(title、name、headline 或 subject),将 #[Sluggable] 注解添加到模型类中,并在 database/migrations 目录下创建一个迁移文件:
use NunoMaduro\LaravelSluggable\Attributes\Sluggable;
#[Sluggable(from: 'title')]
class Post extends Model
{
}Schema::table('posts', function (Blueprint $table) {
$table
->string('slug')
// ->nullable()
->unique()
->after('id');
});在运行迁移之前,请先对其进行审查。如果在运行 php artisan migrate 之前表中已有行,则可能需要将该列设为可空。
之后,将自动生成 slug:
$post = Post::create(['title' => 'Laravel News Rocks']);
$post->slug; // "laravel-news-rocks"配置
所有选项都存在于注解本身。from 和 to 参数控制读取和写入的列,当你想合并多个列时,from 参数接受一个数组:
#[Sluggable(from: ['first_name', 'last_name'], to: 'slug')]
class Author extends Model {}
$author = Author::create(['first_name' => 'John', 'last_name' => 'Tolkien']);
$author->slug; // "john-tolkien"对于多租户应用或任何具有按作用域唯一性的情况,请传递一个作用域(scope)列(或列数组):
#[Sluggable(from: 'title', scope: 'team_id')]其他值得注意的选项包括 maxLength(用于限制 slug 长度)、separator(用于替换破折号)和 onUpdating(用于在源列更改时重新生成 slug)。默认情况下,slug 在创建后会被锁定——无论此设置如何,手动分配的 slug 值始终会保留。
错误处理
如果无法生成 slug,该包会抛出一个 CouldNotGenerateSlugException异常。在 HTTP 上下文中,该异常会自动渲染为带有验证式错误有效负载的 422 响应,因此无需额外操作即可纳入现有的错误处理机制。错误键默认为源列名,但可通过 errorKey 进行覆盖。由于该异常扩展自 ValidationException,因此不会出现在应用日志中。
Unicode 支持
该管道可将非拉丁文字转写为可读的拉丁字母形式,并且具有领域感知能力——看起来像主机名或文件路径的值会保持其点号不变,而不会被替换为破折号。
你可以在项目的 GitHub 仓库中了解更多关于 Laravel Sluggable 的信息。