thunderwolf / sluggable
基于Propel的sluggable行为的Laravel Eloquent的Sluggable插件
Requires
- php: >=8.1
- illuminate/database: ^7.0|^8.0|^9.0|^10.0
- illuminate/events: ^7.0|^8.0|^9.0|^10.0
- illuminate/support: ^7.0|^8.0|^9.0|^10.0
Requires (Dev)
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-09-25 20:32:47 UTC
README
sluggable
行为允许模型提供一个可读的标识符,该标识符可用于搜索引擎友好的URL。
要使用它,需要在您的模型中使用Sluggable
特质,并配置如下所示:
public function sluggable(): array
{
return [];
}
基本用法
使用此包的最基本方法是创建一个使用Sluggable
特质的模型,如下所示:
<?php
use Illuminate\Database\Eloquent\Model;
use Thunderwolf\EloquentSluggable\Sluggable;
class Post extends Model {
use Sluggable; // Attach the Sluggable trait to the model
protected $fillable = ['title'];
public $timestamps = false;
public function sluggable(): array
{
return [];
}
}
注册SluggableServiceProvider
后,您还可以使用蓝图通过createSluggable
辅助方法创建表,如下所示:
$schema->create('posts', function (Blueprint $table1) {
$table1->increments('id');
$table1->string('title');
$table1->createSluggable([]);
});
您将以类似的方式处理迁移。
模型现在有一个额外的getter方法用于其slug,该slug在对象保存之前自动设置。
<?php
$p1 = new Post();
$p1->setAttribute('title', 'Hello, World!');
$p1->save();
echo $p1->getSlug(); // 'hello-world'
默认情况下,行为使用对象的字符串表示形式来构建slug。在上面的例子中,标题列被定义为primaryString,因此slug使用此列作为基本字符串。然后清理字符串,以便它可以出现在URL中。在此过程中,空格和特殊字符被替换为短划线,并且字符串被转换为小写。
设计上slug是唯一的。这意味着如果您创建了一个新的对象,并且行为计算出的slug已经存在,则字符串将被修改以使其唯一。
<?php
$p2 = new Post();
$p2->setAttribute('title', 'Hello, World!');
$p2->save();
echo $p2->getSlug(); // 'hello-world/1'
生成的模型查询提供了一个findOneBySlug
()方法,可以轻松地根据slug检索模型对象。
<?php
$p = Post::findOneBySlug('hello-world');
配置
默认情况下,使用以下配置:
public static function sluggable(): array
{
return [];
}
将向模型添加slug
列。您可以使用以下配置进行配置:
public static function sluggable(): array
{
return ['slug_column' => 'link'];
}
还有其他配置参数,如下所示:
- slug_pattern
- replace_pattern
- replacement
- separator
- permanent
- transliterate
slug_pattern
默认模式是{title}
,它假设将用于生成slug的列是title
。您可以使用不同的模型属性,并且可以使用多个属性。例如,当设置为{title}--{section}
时,slug将是title
和section
的组合,它们之间用--
分隔。任何括号{}
内的子串都将由getAttribute
方法用作键。这意味着您甚至可以创建自己的属性来与其一起使用。
replace_pattern
默认的slugify方法使用的替换模式是/[^\w\/]+/u
。您可以使用任何正则表达式模式。
replacement
替换模式的默认值是-
。
separator
分隔符参数是分隔slug和非唯一性时添加的增量索引的字符。默认设置为/
,使得具有相同标题的Post对象具有以下slug:
'posts/hello-world'
'posts/hello-world/1'
'posts/hello-world/2'
...
permanent
永久slug不会在构成它的字段更改时自动更新。这对于slug用作永久链接时非常有用,即使模型对象的属性更改,该链接也应正常工作。注意,您仍然可以使用永久设置手动更改模型中的slug,通过调用setSlug();
transliterate
如果设置为false
,则不会使用转写。默认设置为true
,并且首先检查intl
是否安装,如果已安装,则使用transliterator_transliterate
函数。如果没有可用,则使用https://github.com/LukeMadhanga/transliterator类来完成类似的工作。
无论您选择什么slug_column名称,sluggable行为总是添加以下代理方法,它们映射到正确的列
<?php
$post->getSlugColumnName() // returns name of the slug column
$post->getSlug(); // returns value of the slug column
$post->getSlugPattern(); // returns slug_pattern configuration value
$post->getReplacePattern(); // returns replace_pattern configuration value
$post->getReplacement(); // returns replacement configuration value
$post->getSeparator(); // returns separator configuration value
$post->isPermanent(); // returns permanent configuration value
$post->shouldTransliterate() // returns transliterate configuration value
进一步定制
当对象保存时,通过createSlug()方法自动生成slug。此方法对简单字符串执行多个操作
/**
* Create a unique slug based on the object
*
* @return string The object slug
* @throws SluggableException
*/
protected function createSlug(): string
{
$slug = $this->createRawSlug($this->getSlugPattern());
$slug = $this->limitSlugSize($slug);
return $this->makeSlugUnique($slug, $this->getSeparator());
}
/**
* Create the slug from the appropriate columns
*
* @param string $slugPattern
* @return string
* @throws SluggableException
*/
protected function createRawSlug(string $slugPattern): string
{
$attributes = SluggableHelper::parseSlugPattern($slugPattern);
$outputArray = [];
foreach ($attributes as $attribute) {
$outputArray['{'.$attribute.'}'] = $this->cleanupSlugPart($this->getAttribute($attribute));
}
return str_replace(array_keys($outputArray), array_values($outputArray), $slugPattern);
}
您可以在模型类中覆盖这些方法中的任何一个,以实现自定义slug逻辑。
待办事项
将执行url清理的代码部分迁移到以下链接之一:
或者这些中的任何一个