rvzug / laravel-seo-urls
当模型保存时,提供自动创建SEO-urls和重定向的功能
Requires
- php: ^8.2
Requires (Dev)
- laravel/pint: ^1.15
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.34
This package is auto-updated.
Last update: 2024-09-29 20:44:54 UTC
README
使用符合SEO规则的sluggable SEO-urls来为模型定义,尊重SEO原则,如规范URL原则,避免重复内容,并跟踪模型的SEO历史URL
正在进行中:这份文档/README是一个快速草案,旨在突出大部分功能。它应该已经涵盖了此包的基本内容。
简介
使用slug是网络应用程序中相对常见的功能,用于定义美观且易于阅读的URL。Laravel本身允许在route model binding
中使用slug,自定义键。此外,还有许多包可以实现将slug作为URL指针指向正确模型的功能。特别是使用Spatie Sluggable包时,可以创建强大的sluggable URL。
这很好,但从搜索引擎优化(SEO)的角度来看,当slug发生变化时存在潜在风险:旧URL不再可达,会导致断链数量增加。如果处理不当,可能会导致SEO惩罚增加和搜索排名下降。
为了防止这种情况,通常的做法是将slug保留为'永久链接',并永远不更新slug。但是,当你故意想要更新slug时,例如当你犯了一个错误,或者你允许最终用户控制slug时,就没有办法修复它。如果你在创建URL后立即这样做,那很好。但是,如果在几周后发现了一个错误,或者决定更改slug更好,你必须手动创建一个重定向。
此包可以实现以下功能:
- 在多个模型上创建(和处理)slug
- 添加更改slug的能力
- 保留旧slug的历史记录
- 自动将旧URL-slug重定向到最新的slug
- 提供多个辅助函数来检索正确的SEO-urls
路由原则
此包假设你已经为模型创建了'非slug路由'。例如,显示一个主题,通常的做法是创建一个处理URL domain.com/topic/{id}
的路由。
例如
Route::get('/topic/{id}', [TopicController::class, 'show'])->name('topic.show');
通常,TopicController::show()
方法将返回一个包含主题视图的响应。该包使用这些路由作为内部路由将用户转发到正确的视图。
此包还假设这些路由上定义了路由名称。
使用此包时,你必须保留这些路由。当SEO URL用于导航到视图时,它将应用程序内部的请求转发到原始定义的路由,同时保留浏览器的SEO URL
domain.com/why-you-should-avoid-broken-links >>-转发->> domain.com/topic/123
浏览器将显示: domain.com/why-you-should-avoid-broken-links
使用内部路由: /topic/123
重定向旧SEO URL
如果使用了旧的{slug}
,此包将重定向浏览器到最新的正确{slug}
。然后转发到内部路由以显示正确的视图
domain.com/why-yuo-should-avoid-brken-lnk >>-301->> domain.com/why-you-should-avoid-broken-links >>-转发->> domain.com/topic/123
浏览器将显示: domain.com/why-you-should-avoid-broken-links
使用内部路由: /topic/123
禁用内部路由
仍然可以浏览到内部URL,例如 domain.com/topic/123
。主题将被显示。如果您不希望这种行为,可以向路由添加提供的 InterceptInternalRoute
中间件
use Rvzug\LaravelSeoUrls\Http\Middleware\InterceptInternalRoute; // ... Route::get('topic/{id}', [TopicController::class, 'show']) ->name('topic.show') ->middleware(InterceptInternalRoute::class)
此中间件将 拦截 内部路由,将浏览器中显示的 seo-url 重定向,然后再次 转发 到内部路由以显示视图。
浏览器将显示: domain.com/why-you-should-avoid-broken-links
使用内部路由: /topic/123
它将使用路由名和提供的路由参数(在本例中:id)来搜索相应的 seo-url。 如果没有找到模型,则返回 ModelNotFoundException / 404错误。
防止重复内容惩罚
如果您想保留内部路由的默认行为,即 domain.com/topic/123
只显示视图而不重定向到 seo-url,您应该在 blade-模板的 <head>
部分实现以下代码片段
<link rel="canonical" href="{{ cannonicalUrl($model) }}" />
有关规范 URL 原则和避免重复内容惩罚的更多信息,请参阅 Google Search Central。
文档
安装
要求包: composer require rvzug/laravel-seo-urls
发布迁移文件: php artisan vendor:publish ...
运行迁移以将 seo_urls 表添加到您的数据库: php artisan migrate
配置
此包默认情况下无需更改配置即可使用。但如果您想更改默认配置,可以发布包配置文件: php artisan vendor:publish ...
默认配置
快速入门
要使用 SEO-urls,您应该将以下三个代码片段实现到您的应用程序中
- 将 HasSeoUrls-trait 添加到应生成 seo-urls 的模型中
// Models/Topic.php use Rvzug\LaravelSeoUrls\Models\Traits\HasSeoUrls class Topic extends Model { use HasSeoUrls; ... }
- 在模型上实现
getRouteName()
-方法,以定义详细路由应指向哪个路由
protected function getRouteName() { return 'topics.show'; }
- 将 seo-url 路由添加到您的路由中,在任何主页路由之后(在定义的任何 回退路由 之前)
// routes/web.php // Default home route Route::get('/', function () { // Original home route return view('welcome'); }); // Added route to handle slugs Route::any('/{slug}', function (string $slug) { return SeoUrls::handleSlug($slug); })->name('seo'); // Fallback route (@see: https://laravel.net.cn/docs/11.x/routing#fallback-routes) Route::fallback(function () { // ... }); // ...
如果您计划在 seo-urls 中使用斜杠(/
),则必须将 ->where('slug', '.*')
方法链接到 slug 路由。请参阅 Laravel 文档。
Route::any('/{slug}', function (string $slug) { return SeoUrls::handleSlug($slug); })->where('slug', '.*')->name('seo');
在此阶段,当创建使用该特质的模型时,它将可在 URL 上使用: domain.com/{model}-{id}
模型
您可以通过在模型中添加 generateSeoUrlSlug()
-方法来更改生成的 slug。
use Illuminate\Support\Str; protected function generateSeoUrlSlug(): string { return Str::slug($this->attributes['title']); }
该方法应返回一个字符串,该字符串定义了您想要的 slug。您可以利用模型的属性,如 $this->title
。有时甚至更好;使用属性数组 $this->attributes['title']
示例:基于日期的 slug
还可以创建一个漂亮的基于日期的 seo-url,例如 /2024/03/01/why-you-should-use-date-pages
use Carbon\Carbon; use Illuminate\Support\Str; protected function generateSeoUrlSlug(): string { return Str::slug(sprintf('%s/%s/%s/%s', (new Carbon($this->attributes['created_at']))->format('Y'), (new Carbon($this->attributes['created_at']))->format('m'), (new Carbon($this->attributes['created_at']))->format('d'), $this->attributes['title']) ); }
保存模型
当保存模型时,slug 将根据以下优先级生成
- 如果您在调用
$model->save()
之前设置了$model->slug
,则将使用此设置 - 如果添加了
generateSeoUrlSlug()
将用作回退 - 包回退是
{{model_name}}-{{primary-key}}
禁用自动保存 seo-url
如果您在保存模型时不希望保存 seo-url,请将 $model->dontUpdateSeoUrl = true;
属性设置为 true
SeoUrl 关系
HasSeoUrls
-trait 为您的模型添加了一个关系 $model->seoUrls()
。这包含一个 SeoUrl
模型的集合。此模型具有以下属性
* model_type
/model_id
是一个 多态关系 到创建 seo-url 的模型
使用 Eloquent 事件 在保存父模型时保存 seo-url 关系。