spatie / laravel-sluggable
在保存 Eloquent 模型时生成 slugs
Requires
- php: ^8.0
- illuminate/database: ^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^6.23|^7.0|^8.0|^9.0
- pestphp/pest: ^1.20|^2.0
- spatie/laravel-translatable: ^5.0|^6.0
- dev-main
- 3.6.0
- 3.5.0
- 3.4.2
- 3.4.1
- 3.4.0
- 3.3.1
- 3.3.0
- 3.2.0
- 3.1.1
- 3.1.0
- 3.0.2
- 3.0.1
- 3.0.0
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.x-dev
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.0
- v1.x-dev
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.2
- 1.0.1
- 1.0.0
- 0.0.1
- dev-dependabot/github_actions/dependabot/fetch-metadata-2.1.0
- dev-phpunit-8
- dev-laravel-5.8
This package is auto-updated.
Last update: 2024-08-29 15:38:38 UTC
README
此包提供了一个特质,可以在保存任何 Eloquent 模型时生成唯一的 slug。
$model = new EloquentModel(); $model->name = 'activerecord is awesome'; $model->save(); echo $model->slug; // outputs "activerecord-is-awesome"
slug 通过 Laravel 的 Str::slug
方法生成,其中空格被转换为 '-'。
Spatie 是一家位于比利时安特卫普的网页设计公司。您可以在我们的网站上找到我们所有开源项目的概述 在这里。
支持我们
我们投入了大量资源来创建 一流的开放式软件包。您可以通过 购买我们的付费产品之一 来支持我们。
我们非常感谢您从您家乡给我们寄明信片,并说明您正在使用我们哪些包。您可以在 我们的联系页面 上找到我们的地址。我们将所有收到的明信片发布在我们的 虚拟明信片墙上。
安装
您可以通过 composer 安装此包
composer require spatie/laravel-sluggable
用法
您的 Eloquent 模型应使用 Spatie\Sluggable\HasSlug
特质和 Spatie\Sluggable\SlugOptions
类。
该特质包含一个抽象方法 getSlugOptions()
,您必须自己实现。
您的模型迁移应有一个字段用于保存生成的 slug。
以下是如何实现该特质的示例
namespace App; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; use Illuminate\Database\Eloquent\Model; class YourEloquentModel extends Model { use HasSlug; /** * Get the options for generating the slug. */ public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug'); } }
及其迁移
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateYourEloquentModelTable extends Migration { public function up() { Schema::create('your_eloquent_models', function (Blueprint $table) { $table->increments('id'); $table->string('slug'); // Field name same as your `saveSlugsTo` $table->string('name'); $table->timestamps(); }); } }
在路由中使用 slugs
要使用生成的 slug 在路由中,请记住使用 Laravel 的 隐式路由模型绑定
namespace App; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; use Illuminate\Database\Eloquent\Model; class YourEloquentModel extends Model { use HasSlug; /** * Get the options for generating the slug. */ public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug'); } /** * Get the route key for the model. * * @return string */ public function getRouteKeyName() { return 'slug'; } }
使用多个字段创建 slug
想要使用多个字段作为 slug 的基础?没问题!
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom(['first_name', 'last_name']) ->saveSlugsTo('slug'); }
自定义 slug 生成
您也可以将一个 callable
传递给 generateSlugsFrom
。
默认情况下,该包将通过在已存在的 slug 后追加 '-' 和一个数字来生成唯一的 slug。
您可以通过调用 allowDuplicateSlugs
来禁用此行为。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->allowDuplicateSlugs(); }
限制 slug 的长度
您也可以对创建的 slug 设置最大尺寸限制
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->slugsShouldBeNoLongerThan(50); }
由于添加了后缀以使其唯一,slug 可能会略长于指定的值。
您也可以通过调用 usingSeparator
使用自定义分隔符
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->usingSeparator('_'); }
设置 slug 语言
要设置 Str::slug
使用的语言,您可以调用 usingLanguage
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->usingLanguage('nl'); }
覆盖 slugs
您也可以通过将其设置为与生成的 slug 不同的值来覆盖生成的 slug。
$model = EloquentModel::create(['name' => 'my name']); //slug is now "my-name"; $model->slug = 'my-custom-url'; $model->save(); //slug is now "my-custom-url";
在某些条件下防止生成 slugs
如果您不想在模型处于某种状态时创建 slug,您可以使用 skipGenerateWhen
函数。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->skipGenerateWhen(fn () => $this->state === 'draft'); }
在创建时防止生成 slugs
如果您不想在模型最初创建时创建 slug,您可以使用 doNotGenerateSlugsOnCreate()
函数。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->doNotGenerateSlugsOnCreate(); }
防止更新 slugs
同样,如果您想防止在模型更新时更新 slug,请调用 doNotGenerateSlugsOnUpdate()
。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->doNotGenerateSlugsOnUpdate(); }
这有助于创建在您明确想要更改之前不会更改的永久链接。
$model = EloquentModel::create(['name' => 'my name']); //slug is now "my-name"; $model->save(); $model->name = 'changed name'; $model->save(); //slug stays "my-name"
重新生成 slugs
如果您想显式更新模型的别名,可以在模型上随时调用generateSlug()
来根据您的其他选项生成别名。别忘了调用save()
来将模型保存到数据库,以持久化更新。
防止覆盖
您可以防止别名被覆盖。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->preventOverwrite(); }
使用作用域
如果您有一个应该考虑的全局作用域,您也可以使用extraScope
来定义它。例如,如果您有一个包含多个网站页面的页面表,每个网站都有自己的唯一别名。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->extraScope(fn ($builder) => $builder->where('scope_id', $this->scope_id)); }
设置别名后缀起始索引
默认情况下,后缀索引从1开始,您可以设置起始数字。
public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug') ->startSlugSuffixFrom(2); }
与laravel-translatable集成
您可以使用此包与laravel-translatable一起使用,为每个区域生成别名。而不是使用HasSlug
特性,您必须使用HasTranslatableSlug
特性,并将别名字段的名称添加到$translatable
数组中。对于从单个字段或多个字段生成的别名,您不需要更改其他任何内容。
namespace App; use Spatie\Sluggable\HasTranslatableSlug; use Spatie\Sluggable\SlugOptions; use Spatie\Translatable\HasTranslations; use Illuminate\Database\Eloquent\Model; class YourEloquentModel extends Model { use HasTranslations, HasTranslatableSlug; public $translatable = ['name', 'slug']; /** * Get the options for generating the slug. */ public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug'); } }
对于从可调用生成的别名,您需要使用createWithLocales
方法实例化SlugOptions
。现在可调用接受两个参数,而不是一个。现在,$model
和$locale
都可用于生成别名。
namespace App; use Spatie\Sluggable\HasTranslatableSlug; use Spatie\Sluggable\SlugOptions; use Spatie\Translatable\HasTranslations; use Illuminate\Database\Eloquent\Model; class YourEloquentModel extends Model { use HasTranslations, HasTranslatableSlug; public $translatable = ['name', 'slug']; /** * Get the options for generating the slug. */ public function getSlugOptions() : SlugOptions { return SlugOptions::createWithLocales(['en', 'nl']) ->generateSlugsFrom(function($model, $locale) { return "{$locale} {$model->id}"; }) ->saveSlugsTo('slug'); } }
隐式路由模型绑定
您还可以在控制器中使用Laravel的隐式路由模型绑定来自动解析模型。要使用此功能,请确保别名列与routeNameKey
匹配。
目前,只有一些数据库类型支持JSON操作。有关支持JSON的数据库的更多信息,请参阅Laravel文档。
namespace App; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; use Illuminate\Database\Eloquent\Model; class YourEloquentModel extends Model { use HasTranslations, HasTranslatableSlug; public $translatable = ['name', 'slug']; /** * Get the options for generating the slug. */ public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('name') ->saveSlugsTo('slug'); } /** * Get the route key for the model. * * @return string */ public function getRouteKeyName() { return 'slug'; } }
通过别名查找模型
为了方便,您可以使用别名findBySlug
来检索模型。查询将比较在定义SlugOptions
时传递给saveSlugsTo
的字段。
$model = Article::findBySlug('my-article');
findBySlug
也接受一个第二个参数$columns
,就像默认的Eloquent find
方法一样。
更新日志
请参阅更新日志了解最近更改的更多信息。
测试
composer test
贡献
请参阅贡献指南以获取详细信息。
安全
如果您发现有关安全性的错误,请通过security@spatie.be发送邮件,而不是使用问题跟踪器。
鸣谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。