博客已经开发完成了,准备上线的时候发现一个问题,原来博客文章详情的 URL 是 https://www.sevdot.com/post/week-10-retrospective/
这样的,现在博客文章详情的 URL 是 http://blog.test/blog/51
的,相比之下,原来的 URL 更好,释义的 URL 有助于搜索引擎优化(SEO)。
此外,如果与原来的 URL 不一致,那么以前 URL 的就打不开,一些被搜索引擎收录的链接就打不开了。
添加 slug 字段
需要给 articles
文章数据表添加一个 slug
字段,用来存放文章标题翻译的内容,现在为 slug
字段新增一个迁移,运行如下命令生成迁移文件:
php artisan make:migration add_slug_to_articles_table --table=articles
现在来为迁移文件加上 slug
字段。
database/migrations/[timestamp]_add_slug_to_articles_table.php
<?php use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('articles', function (Blueprint $table) {
$table->string('slug')->nullable();
});
}
public function down()
{
Schema::table('articles', function (Blueprint $table) {
$table->dropColumn('slug');
});
}
};
接着还需要运行迁移,将字段加入到文章表中:
php artisan migrate
修改管理后台
需要修改管理后台的文章管理,添加和编辑文章的时候可以输入 slug
字段,修改后台文章控制器的 form
方法。
app/Admin/Controllers/ArticlesController
protected function form()
{
$columns = Column::pluck('name', 'id')->toArray();
return Form::make(new Article(), function (Form $form) use ($columns) {
$form->display('id');
$form->select('column_id')->options($columns);
$form->text('title');
$form->text('slug','翻译标题');
$form->markdown('content');
$form->display('created_at');
$form->display('updated_at');
});
}
修改路由
在 routes/web.php
文件中,找到以下这两行:
Route::get('/blog/{article}/{slug?}', [ArticlesController::class, 'show'])->name('articles.show');
URI 参数 topic
是『隐性路由模型绑定』的提示,将会自动注入 ID 对应的文章实体。URI 最后一个参数表达式 {slug?} ,? 意味着参数可选,这是为了兼容数据库中 Slug 为空的文章数据。这种写法可以同时兼容以下两种链接:
http://blog.test/blog/1
http://blog.test/blog/1/slug
新增 link
方法
在文章模型中添加 link
方法。
app/Models/Article.php
.
.
.
class Article extends Model
{
.
.
.
public function link($params = []){
return route('articles.show', array_merge([$this->id, $this->slug], $params));
}
}
修改视图
修改article_list.blade.php
视图文件,找到如下:
<a class="is-flex" href="%7B%7Broute('article.show',%24value->id)%7D%7D" title="{{$value->title}}">
{{$value->title}}
</a>
修改为:
<a class="is-flex" href="%7B%7B%20%24value->link()%20%7D%7D" title="{{$value->title}}">
{{$value->title}}
</a>
添加路由
为了让原来的文章详情的 URL 能正常打开,再添加一条路由。
routes/web.php
Route::get('/post/{slug}', [ArticlesController::class, 'getDetailBySlug'])->name('post.show');
添加 getDetailBySlug
方法
app/Http/Controllers/ArticlesController.php
public function getDetailBySlug($slug,Parsedown $parsedown){
$article = Article::where('slug',$slug)->first();
if (!$article){
return redirect()->route('root');
}
$article->content = $parsedown->parse($article->content);
return view('articles.show',compact('article'));
}