thunderwolf/sluggable

基于Propel的sluggable行为的Laravel Eloquent的Sluggable插件

1.0.1 2024-08-25 22:17 UTC

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将是titlesection的组合,它们之间用--分隔。任何括号{}内的子串都将由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清理的代码部分迁移到以下链接之一:

或者这些中的任何一个