expstudio / friendly-url
使用PHP5.3.x和非拉丁字符支持,在Laravel 4中轻松创建Eloquent模型的路由别名或友好URL。
Requires
- php: >=5.4.0
- illuminate/config: 4.*
- illuminate/database: 4.*
- illuminate/support: 4.*
Requires (Dev)
- laravelbook/ardent: dev-master
- orchestra/testbench: 2.*
- phpunit/phpunit: 4.0.*
This package is not auto-updated.
Last update: 2024-09-28 16:25:49 UTC
README
在Laravel 4中轻松为Eloquent模型创建路由别名。
背景:什么是路由别名?
路由别名是字符串的简化版本,通常是URL友好的。将字符串“路由别名化”通常涉及将其转换为单一大小写,并删除任何非URL友好的字符(空格、重音字母、和号等)。生成的字符串可以用来标识特定的资源。
例如,我有一个包含帖子内容的博客。我可以通过ID引用每个帖子
http://example.com/post/1
http://example.com/post/2
...但这并不特别友好(特别是对于SEO)。你可能更喜欢使用帖子的标题作为URL,但如果帖子的标题是“我与安德烈和弗朗索瓦共进晚餐”,那么这也会很丑陋
http://example.com/post/My+Dinner+With+Andr%C3%A9+%26+Fran%C3%A7ois
解决方案是为标题创建一个路由别名并使用它。你可能想使用Laravel内置的Str::slug()
方法将标题转换为更友好的形式
http://example.com/post/my-dinner-with-andre-francois
这样的URL会让用户更满意(可读性更强,更容易输入等)。
更多信息,你可能想阅读维基百科上的这篇描述。
路由别名通常也是唯一的。所以如果我再写一篇标题相同的帖子,我需要以某种方式区分它们,通常是在路由别名末尾添加一个递增计数器
http://example.com/post/my-dinner-with-andre-francois
http://example.com/post/my-dinner-with-andre-francois-1
http://example.com/post/my-dinner-with-andre-francois-2
这保持了URL的唯一性。
Laravel 4的
安装和需求
首先,您需要将包添加到composer.json
文件的require
属性中
{ "require": { "expstudio/friendlyurl": "dev-master" }, }
注意:Eloquent-Sluggable现在使用特性,因此您需要运行PHP 5.4或更高版本。如果您仍在使用5.3,请使用“1.*”版本,并遵循该版本README.md文件中的说明。
然后,从命令行运行composer update
。
然后,通过添加服务提供者的条目来更新app/config/app.php
。
'providers' => array( // ... 'Expstudio\FriendlyUrl\SluggableServiceProvider', );
最后,再次从命令行运行php artisan config:publish expstudio/friendlyurl
以发布默认配置文件。
更新你的Eloquent模型
您的模型应实现Sluggable的接口并使用其特性。您还应定义一个受保护的属性$sluggable
,其中包含任何特定于模型的配置(有关详细信息,请参阅下面的配置)
use Expstudio\FriendlyUrl\SluggableInterface; use Expstudio\FriendlyUrl\SluggableTrait; class Post extends Eloquent implements SluggableInterface { use SluggableTrait; protected $sluggable = array( 'build_from' => 'title', 'save_to' => 'slug', ); }
当然,您的数据库需要一个用于存储别名的列。您可以手动操作,或使用内置的Artisan命令为您创建迁移。例如
php artisan sluggable:table posts
运行该命令将在您的帖子表中添加一个名为“slug”的列。如果您想为别名列使用不同的名称,您可以将其作为第二个参数提供
php artisan sluggable:table posts slug_column
确保设置模型的save_to
配置以匹配列名。
就是这样...您的模型现在可以“路由别名化”了!
使用类
保存模型很简单
$post = new Post(array( 'title' => 'My Awesome Blog Post' )); $post->save();
检索别名也同样简单
echo $post->slug; // or, if you don't know the name of the slug attribute: echo $post->getSlug();
请参阅 README-Ardent.md 文件,了解如何在使用 Ardent 时使用 Eloquent-Sluggable。
注意:如果您正在使用 Eloquent 的 replicate()
方法复制模型,那么您需要显式告诉包在之后强制重新生成模型的 slugging,以确保唯一性。
$new_post = $post->replicate()->resluggify();
配置
配置设计得尽可能灵活。您可以设置所有 Eloquent 模型的默认值,然后为单个模型覆盖这些设置。
默认情况下,全局配置可以在 app/config/packages/expstudio/friendlyurl/config.php
文件中设置。如果没有设置配置,则使用 vendor/expstudio/friendlyurl/src/config/config.php
中的包默认值。以下是一个配置示例,显示了所有默认设置:
return array( 'build_from' => null, 'save_to' => 'slug', 'max_length' => null, 'method' => null, 'separator' => '-', 'unique' => true, 'include_trashed' => false, 'on_update' => false, 'reserved' => null, 'use_cache' => false, );
build_from
这是构建 slug 字段或字段数组。每个 $model->field
将通过空格分隔连接起来,以构建可 slugging 字符串。这可以是模型属性(即数据库中的字段)或自定义获取器。例如,这可以工作:
class Person extends Eloquent implements SluggableInterface { use SluggableTrait; public static $sluggable = array( 'build_from' => 'fullname' ); public function getFullnameAttribute() { return $this->firstname . ' ' . $this->lastname; } }
如果 build_from
为空、false 或 null,则使用 $model->__toString()
的值。
save_to
这是模型中存储 slug 的属性字段。默认情况下,这是 "slug"。当定义模式时,您需要在表中创建此列。
Schema::create('posts', function($table) { $table->increments('id'); $table->string('title'); $table->string('body'); $table->string('slug'); $table->timestamps(); });
max_length
将此设置为正整数将确保生成的 slug 限制在最大长度内(例如,以确保它们适合您的数据库字段)。默认情况下,此值是 null,不强制执行限制。
注意:如果启用 unique
(默认启用),并且您预计会有多个模型具有相同的 slug,则应将此值设置为数据库字段长度略短。原因在于,类将为后续模型附加 "-1"、" "-2"、" "-3",等等,以保持唯一性。这些增量扩展不包括在 max_length
计算中。
method
定义将可 slugging 字符串转换为 slug 使用的函数。此配置有三个可能的选项:
-
当
method
为 null(默认设置)时,包使用修改后的 Laravel 的Str::slug()
方法来创建 slug。 -
当
method
是可调用的函数或类方法时,则使用该函数或方法。函数/方法应期望两个参数:要处理的字符串和分隔符字符串。例如,要复制默认行为,您可以这样做:'method' => array('Illuminate\\Support\\Str', 'slug'),
-
您还可以将
method
定义为闭包(同样,期望两个参数)'method' => function( $string, $separator ) { return strtolower( preg_replace('/[^a-z]+/i', $separator, $string) ); },
其他 method
的值将抛出异常。
对于更复杂的 slugging 要求,请参阅下面的 扩展 Sluggable。
separator
这定义了构建 slug 时使用的分隔符,并将其传递给上面定义的 method
。默认值是连字符。
unique
这是一个布尔值,定义 slugs 是否应在给定类型的所有模型中保持唯一。例如,如果您有两个名为 "My Blog Post" 的博客文章,那么它们都将使用 Sluggable 的默认设置转换为 "my-blog-post"。这可能会成为问题,例如如果您在 URL 中使用 slug。
开启 unique
后,第二个文章模型将转换为 "my-blog-post-1"。如果有第三个具有相同标题的文章,它将转换为 "my-blog-post-2",依此类推。每个后续模型都会在 slug 的末尾附加一个增量值,以确保唯一性。
include_trashed
将此设置为 true
将也会在尝试强制唯一性时检查已删除的模型。这仅影响使用 软删除 功能的 Eloquent 模型。默认值为 false
,因此检查唯一性时不会计算软删除的模型。
on_update
一个布尔值。如果它是 false
(默认值),那么在模型重新保存时(例如,如果您更改博客文章的标题,则 slug 将保持不变)或 slug 值已被设置时,slugs 不会更新。如果您想覆盖此行为,可以将其设置为 true
(或在您的代码中手动更改 $model->slug 值)。
(如果您想使用模型的自定义 Sluggable 设置手动设置 slug 值,可以运行 $model->resluggify()
来强制 Sluggable 更新 slug 字段。)
reserved
一个数组,其中的值永远不会被允许作为 slugs,例如,为了防止与现有路由或控制器方法等冲突。这可以是一个数组,也可以是一个返回数组的闭包。默认值为 null
:没有保留的 slug 名称。
use_cache
在检查唯一性时,该包将查询数据库以获取具有相同或类似 slugs 的任何现有模型,然后检查是否需要增量。这意味着更多的数据库使用,如果在同一时间保存大量模型,也可能导致竞争条件。
开启 use_cache
将使用 Laravel 的缓存存储最后生成的增量,以便您的应用程序可以节省这些数据库请求。
默认值是 false
:不使用缓存。如果您已经使用支持 Cache::tags()
功能(即除了数据库和文件缓存以外的任何内容)的缓存系统,那么您真的应该启用此设置。将其更改为正整数,表示在缓存中存储 slug 信息的分钟数。
(如果您出于任何原因想清除 Sluggable 的所有缓存条目,只需运行 Cache::tags('sluggable')->flush()
。)
扩展Sluggable
有时配置选项不足以满足复杂需求(例如,可能需要考虑其他属性的唯一性测试,或者可能需要为同一模型生成两个 slugs)。
在这种情况下,您的最佳选择是在每个模型的基础上重载一些 SluggableTrait 的方法,或者是在扩展 SluggableTrait 的您自己的特质中。每个步骤都会分解为它自己的方法,并在生成 slug 时依次调用这些方法。
查看 SluggableTrait->sluggify()
以查看操作顺序,但您可以考虑重载以下受保护的任何方法
needsSlugging()
确定模型是否需要 slugging。应返回一个布尔值。
getSlugSource()
返回一个字符串,该字符串形成 slug 的来源(通常基于 build_from
配置值)。
generateSlug($source)
实际的 slugging 代码。通常实现 method
配置中定义的内容,但可能调用其他 slugging 库。接收源字符串(上面)并返回一个字符串。
validateSlug($slug)
验证生成的 slug 是否有效,通常通过将其与 reserved
配置中定义的内容进行比较。应返回一个有效的 slug 字符串。
makeSlugUnique($slug)
检查给定的 slug 是否唯一。应返回一个唯一的 slug 字符串。
setSlug($slug)
将(生成的、有效的和唯一的)slug 写入模型属性。
错误、建议和贡献
请使用 Github 进行错误、评论和建议。
- 分叉项目。
- 创建您的错误修复/功能分支并编写您的(注释良好的)代码。
- 为您的代码创建单元测试。
- 在根目录中运行
composer install --dev
以安装所需的测试包。 - 将您的测试方法添加到
eloquent-sluggable/tests/SluggableTest.php
。 - 运行
vendor/bin/phpunit
以运行新(以及所有以前)的测试,并确保一切通过。
- 在根目录中运行
- 提交您的更改(以及您的测试)并推送到您的分支。
- 创建一个新的拉取请求,针对eloquent-sluggable的
develop
分支。
请注意,您必须针对develop
分支创建您的拉取请求。
版权和许可证
Laravel4友好URL已被Watee Wichiennit从Eloquent-Sluggable修改并发布在MIT许可证下。有关详细信息,请参阅LICENSE文件。
版权所有 2014 Watee Wichiennit