laravel博客项目实战.4--博客首页

254 阅读2分钟

前面我们写了怎么添加博客,这篇文章我们讲解博客首页怎么实现,我们主要用到的laravel功能如下

  • 自定义中间件
  • 视图共享数据
  • 路由匹配规则
  • 路由约束

首先我们定义一条新的路由

Route::get('/{id?}', 'BlogController@getBlogList')->where('id', '[0-9]+');

Route::get('/category/{id?}.html', 'BlogController@getBlogList')->where('id', '[0-9]+');

路由规则说明

  • {id?} 表示这里的id可选
  • where('id', '[0-9]+') 表示id的正则约束规则 所以这条规则对应的地址可以是:“/”,“/1”,"/2"

自定义中间件

我们执行如下命令,新增一条中间件

php artisan make:middleware Web

中间件的存储位置

app/Http/Middleware/Web.php

修改中间件的内容如下

<?php

namespace App\Http\Middleware;

use App\Models\Category;
use Closure;

class Web
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        view()->share('navCategoryList', Category::where('parent_id', 0)->get());
        return $next($request);
    }
}

注意下面这段代码,他表示,给视图赋值,从而让拥有这个中间件的所有视图都有这些数据,所以,要小心键的冲突

对应的SQL: select * from categories。get方法表示拿到所有数据。

    view()->share('navCategoryList', Category::where('parent_id', 0)->get());

注册中间件

修改app/Http/Kernel.php文件

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'lee.web' => Web::class,

    ];

下面这句话,我们自己命名中间件的名字为lee.web

    'lee.web' => Web::class,

使用中间件

还记得我们app/Providers/RouteServiceProvider.php这个文件么?我们当初统一修改web路由的命名空间。这里我们定义的中间件是通用的,为了给网站顶部分类使用,所以也需要应用的全部路由里面。修改我们的代码如下:

    protected function mapWebRoutes()
    {
        //修改为我们自己定会的命名空间
        Route::middleware(['web', 'lee.web'])
            ->namespace($this->namespaceWeb)
            ->group(base_path('routes/web.php'));
    }

这样我们web下所有的路由都拥有了这个中间件,从而达到多个页面数据共享。

修改BlogController和BlogRepository

BlogController

    public function getBlogList($categoryId = null)
    {
        $blogList = $this->blogRepository->getBlogList($categoryId);
        $goodList = $this->blogRepository->getGoodList();
        return view('web.blog.index', ['blogList' => $blogList, 'goodList' => $goodList]);
    }

我们路由定义的id就会作为参数传递过来,如果的你参数是可选的,可以在controller里的方法中给默认值,我里给$categoryId的默认值为null

BlogRepository

    public function getBlogList($categoryId = null)
    {
        return Blog::leftjoin('categories', 'blogs.category_id', '=', 'categories.id')
            ->orderby('blogs.id', 'desc')
            ->select('blogs.*')
            ->where(function ($q) use ($categoryId) {
                if ($categoryId) {
                    $q->where('categories.parent_id', $categoryId);
                }
            })
            ->paginate();
    }

这里我们用到了链表查询,leftjoin表示左连接,第一个参数表示例外一张表,第二和第四个参数表示表中的联结字段,第三个参数“=”固定写法。

这里我们用到了闭包,我们判断$categoryId是否存在,存在的话增加where条件。

模板继承

我们定义一下模板,作为公共模板

resources/views/web/layouts/app.blade.php

模板示例如下

这里用到了模板语法yield,他定义了一个可替换的位置

我们修改首页的模板


resources/views/web/blog/index.blade.php

下面这句话表示继承模板

@extends('web.layouts.app')


@section('title', '添加博客;')//替换我们@yield('title'),下面雷同
@section('keywords', '添加博客;')
@section('description', '添加博客;')

最总效果如下图

但是,当我们点击分类,怎么实现分类高亮呢?

        <ul class="navbar-nav mr-auto">
            @foreach($navCategoryList as $nav)
                <li class="nav-item @if(request()->path()=='category/'.$nav->id.'.html') active @endif">
                    <a class="nav-link"
                       href="/category/{{$nav->id}}.html">{{$nav->category_name}}</a>
                </li>
            @endforeach
        </ul>

这里我们用到了if语法,同时request()->path()可以获得我们的url片段,最终给我们的导航条加上高亮效果。

回顾一下我们用到的技术点

  • 中间件
  • 路由的正则约束
  • 路由可选参数
  • 视图数据共享
  • 模板继承
  • 模板中的逻辑判断
  • leftjoin查询数据
  • 如何使用闭包查询数据