前面已经完成了博客文章列表的展示页面,现在要来完成博客文章的详情页面。
添加路由
现在添加定义文章详情页的路由,用于展示文章详情。routes/web.php
。
<?php
use App\Http\Controllers\ArticlesController;
use App\Http\Controllers\PagesController;
use Illuminate\Support\Facades\Route;
Route::get('/', [PagesController::class, 'root'])->name('root');
Route::get('/about', [PagesController::class, 'about'])->name('about');
Route::get('/contact', [PagesController::class, 'contact'])->name('contact');
Route::get('/blog', [ArticlesController::class, 'index'])->name('articles');
Route::get('/blog/{article}', [ArticlesController::class, 'show'])->name('article.show');
修改控制器
在ArticlesController
文章控制器中定义 show
方法:app/Http/Controllers/ArticlesController.php
。
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
class ArticlesController extends Controller
{
public function index(){
$articles = Article::orderBy('created_at', 'desc')->paginate(10);
return view('articles.index',compact('articles'));
}
public function show(Article $article){
return view('articles.show',compact('article'));
}
}
Laravel 会自动解析定义在控制器方法(变量名匹配路由片段)中的 Eloquent 模型类型声明。在上面代码中,由于 show()
方法传参时声明了类型 —— Eloquent 模型 Article
,对应的变量名 $articles
会匹配路由片段中的 {article}
,这样,Laravel 会自动注入与请求 URI 中传入的 ID 对应的用户模型实例。
此功能称为 『隐性路由模型绑定』,是『约定优于配置』设计范式的体现,同时满足以下两种情况,此功能即会自动启用:
- 路由声明时必须使用 Eloquent 模型的单数小写格式来作为路由片段参数,Article 对应
{article}
:
Route::get('/blog/{article}', [ArticlesController::class, 'show'])->name('article.show');
- 控制器方法传参中必须包含对应的 Eloquent 模型类型声明,并且是有序的:
public function show(Article $article){
return view('articles.show',compact('article'));
}
当请求 blog.test/blog/1
并且满足以上两个条件时,Laravel 将会自动查找 ID 为 1 的文章并赋值到变量 $article
中,如果数据库中找不到对应的模型实例,会自动生成 HTTP 404 响应。
添加详情页视图
接下来新建一个文章详情页面。resources/views/articles/show.blade.php
。
@extends('layouts.app')
@section('title')
{{$article->title}}
@stop
@section('meta')
<meta name="description" content="{{$article->excerpt}}" />
@endsection
@section('content')
<section class="section">
<div class="container is-max-widescreen">
<div class="columns">
<div class="column is-9">
<div class="box ">
<h1 class="title is-3 mt-2 mb-1 has-text-centered">{{$article->title}}</h1>
<div class="has-text-centered">
<span class="is-size-7 has-text-grey">发布日期 {{$article->created_at->toDateString()}}</span>
</div>
<hr class="mt-2 mb-4">
<div class="content">
{!! $article->content !!}
</div>
</div>
</div>
<div class="column is-3">
<div class="box">
<p class="has-text-centered">站长:<a href="{{url('/contact')}}" target="_blank">SevDot</a></p>
<hr>
<div class="is-flex is-justify-content-center">
<figure class="image is-96x96">
<img class="is-rounded" style="" src="{{asset('images/sevdot_avatar.jpg')}}" alt="SevDot 的头像">
</figure>
</div>
<hr>
<div class="has-text-centered">
<a href="" class="button is-light"><span class="icon"><i
class="fa fa-github"></i></span></a>
<a href="" class="button is-info"><span class="icon"><i class="fa fa-weibo"></i></span></a>
<a href="" class="button is-success"><span class="icon"><i class="fa fa-weixin"></i></span></a>
</div>
</div>
<div class="box">
<h2 class="title is-5 has-text-centered has-text-success">微信公众号</h2>
<hr>
<img src="{{asset('images/sevdots.png')}}" alt="">
</div>
</div>
</div>
</div>
</section>
@stop
展示
使用浏览器访问 [http://blog.test/blog/1](http://blog.test/blog)
可以看到文章详情页如下所示: