基于Laravel开发博客应用系列 —— 构建博客后台管理系统
一个完整的博客应用不能没有后台管理系统。所以在本节中我们将继续完善博客应用 —— 开发后台管理系统。
1、创建路由
在上一节十分钟创建博客项目中,已经设置过了 app/Http/routes.php,现在,我们要添加后台路由到该文件。
为什么要使用路由?
Laravel 5.1 一种机制用来建立 web 请求与处理 web 请求的代码之间的关系,这种机制被称作路由。本项目中所有路由都定义在 app/Http/routes.php 文件中。
只要 web 请求路径在 public 目录下找不到,Laravel 5.1 就会从路由文件查找对应关系并返回响应。
修改 app/Http/routes.php 内容如下:
<?php // Blog pages
get('/', function () {
return redirect('/blog');
});
get('blog', 'BlogController@index');
get('blog/{slug}', 'BlogController@showPost'); // Admin area
get('admin', function () {
return redirect('/admin/post');
});
$router->group(['namespace' => 'Admin', 'middleware' => 'auth'], function () {
resource('admin/post', 'PostController');
resource('admin/tag', 'TagController');
get('admin/upload', 'UploadController@index');
}); // Logging in and out
get('/auth/login', 'Auth\AuthController@getLogin');
post('/auth/login', 'Auth\AuthController@postLogin');
get('/auth/logout', 'Auth\AuthController@getLogout');
保存好 routes.php 后,下一步我们要创建对应的控制器。
2、创建后台控制器
使用 Artisan 命令生成控制器:
php artisan make:controller Admin\\PostController
php artisan make:controller Admin\\TagController
php artisan make:controller Admin\\UploadController --plain
上述三个命令运行完成后,会在 app/Http/Controllers/Admin 目录下生成三个控制器。
修改 PostController 类的 index() 方法如下:
/**
* Display a listing of the posts.
*
* @return Response
*/
public function index()
{
return view('admin.post.index');
}
现在 index() 方法只是简单渲染视图,稍后我们会完善它。
3、创建视图
我们还需要创建一些视图,一步步来好了。
创建后台布局
Blade 模板引擎是 Laravel 提供的最强大的功能之一,接下来我们将基于 Blade 创建一个供后台使用的布局文件,从而让后台有一个整体外观一致的视觉体验。
在 resources/views 目录下新建一个 admin 目录,然后在该目录下创建一个 layout.blade.php 文件并编辑其内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{ config('blog.title') }} Admin</title> <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
@yield('styles') <!--[if lt IE 9]>
<script src="//oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body> {{-- Navigation Bar --}}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-menu">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{{ config('blog.title') }} Admin</a>
</div>
<div class="collapse navbar-collapse" id="navbar-menu">
@include('admin.partials.navbar')
</div>
</div>
</nav> @yield('content') <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> @yield('scripts') </body>
</html>
上面的代码片段可能看上去很熟悉,没错,这就是 Bootstrap 的基本模板,我们只是在其基础上加了一些额外的钩子:
<title>{{ config('blog.title') }} Admin</title>: 设置站点标题@yield('styles'):该 Blade 指令将会输出继承自该布局的子视图的styles区块内容(如果有的话),其目的在于将 CSS 样式文件放到模板顶部。@include('admin.partials.navbar'):这里我们引入另一个 Blade 模板(现在还不存在)@yield('content'):输出页面的主体内容@yield('scripts'):输出额外的JavaScript脚本文件
创建导航条局部视图
在 resources/views/admin 目录下新建 partials 目录,并在该目录下创建 navbar.blade.php 文件,编辑其内容如下:
<ul class="nav navbar-nav">
<li><a href="/">Blog Home</a></li>
@if (Auth::check())
<li @if (Request::is('admin/post*')) class="active" @endif>
<a href="/admin/post">Posts</a>
</li>
<li @if (Request::is('admin/tag*')) class="active" @endif>
<a href="/admin/tag">Tags</a>
</li>
<li @if (Request::is('admin/upload*')) class="active" @endif>
<a href="/admin/upload">Uploads</a>
</li>
@endif
</ul> <ul class="nav navbar-nav navbar-right">
@if (Auth::guest())
<li><a href="/auth/login">Login</a></li>
@else
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-expanded="false">
{{ Auth::user()->name }}
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="/auth/logout">Logout</a></li>
</ul>
</li>
@endif
</ul>
如果用户登录进来,该模板会显示一个顶部导航条:左侧包含 Posts、Tags 和 Uploads,右侧包含 Logout。
如果用户没有登录,只在导航条右侧显示 Login 链接。
创建登录表单
现在我们已经有了后台布局视图,创建登录表单不要太简单,首先在 resources/views 目录下新建 auth 目录,并在该目录下创建 login.blade.php 文件,编辑该文件内容如下:
@extends('admin.layout')
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Login</div>
<div class="panel-body">
@include('admin.partials.errors')
<form class="form-horizontal" role="form" method="POST"
action="{{ url('/auth/login') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<label class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input type="email" class="form-control" name="email" value="{{ old('email') }}" autofocus>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password">
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
在登录表单中我们引入了一个尚未创建的 admin.partials.errors,接下来就来创建该视图:
创建错误局部视图
验证表单输入错误并在视图中显示这些错误在处理表单时是一个通用任务,所以我们将其放到一个单独的 Blade 模板视图中进行处理。
在 resources/views/admin/partials 目录下创建 errors.blade.php,编辑其内容如下:
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong>
There were some problems with your input.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
$errors 变量在每个视图中都有效,其中包含了一个错误集合(如果有错误的话),我们只需要检查是否包含错误并将错误显示出来即可。
创建文章列表视图
在 resources/views/admin 目录下创建一个新的目录 post,并在该目录下新建 index.blade.php,编辑该文件内容如下:
@extends('admin.layout')
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Posts</h3>
</div>
<div class="panel-body">
TODO
</div>
</div>
</div>
</div>
</div>
@stop
这只是一个临时视图,后面我们会逐步完善它。
4、测试登录/退出
在浏览器中访问 http://blog.app/admin,回跳转到登录页面,页面显示如下:

你可以试着登录,当然你不可能登录成功,因为我们还没有创建后台用户。
创建后台用户
artisan tinker 可以用于通过命令行与应用进行交互,下面我们在 Homestead 虚拟机中项目根目录下使用该命令为博客项目创建后台用户:

现在我们就可以使用刚刚创建的用户登录后台了。回到登录页试试吧。
登录成功后页面跳转到文章列表页:

修改退出后跳转 URL
如果点击页面顶部导航条右侧的下拉列表并选择 Logout 退出,你会发现页面没有跳转到登录页面,而是博客页面。
为什么会这样?
如果查看 AuthController 类(app/Http/Controllers/Auth/AuthController)的 getLogout() 方法,你会发现并没有该方法,在其父类中也没有 getLogout() 方法,这是因为 AuthController 使用了AuthenticatesAndRegistersUsers trait 和 AuthenticatesUsers trait,getLogout() 方法正是定义在了AuthenticateUsers trait 中。
如果你在 vendor/laravel/framework/src 目录下找到 Illuminate/Foundation/Auth 目录,你会发现该目录下有一个 AuthenticatesUsers.php,在该文件中,可以看到 getLogout() 方法,并且该方法在退出完成后重定向到了根路径 / 。
要修改该重定向路径,修改 app/Http/Controllers/Auth/AuthController 代码如下:
<?php namespace App\Http\Controllers\Auth; use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesUsers; class AuthController extends Controller
{
use AuthenticatesUsers, ThrottlesLogins; protected $redirectAfterLogout = '/auth/login';
protected $redirectTo = '/admin/post'; /**
* Create a new authentication controller instance.
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
} /**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
}
我们移除了 AuthenticateAndRegistersUsers trait,因为我们的应用不允许普通用户注册。然后我们设置了 $redirectAfterLogout 属性和 $redirectTo 属性,用来指定登录和退出后的重定向 URL。
该类的其余部分和之前一样保持不变。
修改登录后跳转 URL
默认登录成功后跳转链接是 /home,和退出一样,我们可以修改该URL。
编辑 app/Http/Middleware/RedirectIfAuthenticated.php 文件,修改第38行代码如下:
return new RedirectResponse('/admin/post');
登录/退出
由于现在我们已经将 getLogout() 方法的跳转链接做了修改,现在我们已经可以成功实现登录/退出了。
试试吧。
基于Laravel开发博客应用系列 —— 构建博客后台管理系统的更多相关文章
- 基于 Laravel 开发博客应用系列 —— 设置 Linux/Mac 本地开发环境
1.不同 Linux 发行版本的区别 不同的 Linux 发行版本之间有一些细微区别,尤其是包管理器:CentOS 和 Fedora 使用 yum 作为包管理器,而Ubuntu 使用 apt,在 O ...
- 基于 Laravel 开发 ThinkSNS+ 中前端的抉择(webpack/Vue)踩坑日记【ThinkSNS+研发日记系列】
在上一篇文章< ThinkSNS+基于Laravel master分支,从1到 0,再到0.1>,简单的介绍了 社群系统ThinkSNS+ ,这里分享在开发过程中,前端选择的心理活动. L ...
- 基于 Laravel 开发 ThinkSNS+ 中前端的抉择(webpack/Vue)踩坑日记
在上一篇文章< ThinkSNS+基于Laravel master分支,从1到 0,再到0.1>,简单的介绍了 ThinkSNS+ ,这里分享在开发过程中,前端选择的心理活动. Larav ...
- 基于 Laravel 开发博客应用系列 —— 项目必备软件安装
1.概述 通过本项目我们将会构建一个简单.清爽.优雅的博客系统,以及维护管理该博客的后台. 本项目源码公开在GitHub上:https://github.com/ChuckHeintzelman/l5 ...
- 基于 Laravel 开发博客应用系列 —— 从测试开始(二):使用Gulp实现自动化测试
3.使用 Gulp 进行 TDD(测试驱动开发) Gulp 是一个使用 JavaScript 编写的自动化构建工具.用于对前端通用任务(如最小化.压缩.编译)进行自动构建.Gulp 还可以用来监控源代 ...
- 基于Laravel开发博客应用系列 —— 使用Bower+Gulp集成前端资源
本节我们将讨论如何将前端资源集成到项目中,包括前端资源的发布和引入.本项目将使用 Bower 和 Gulp 下载和集成jQuery.Bootstrap.Font Awesome 以及 DataTabl ...
- 基于 Laravel 开发博客应用系列 —— 从测试开始(一):创建项目和PHPUnit
1.创建博客项目 我们将遵循上一节提到的六步创建一个新 Laravel 5.1 项目的步骤,创建本节要用到的博客项目 —— blog. 首先,在本地主机安装应用骨架: nonfu@ubuntu:~/C ...
- 基于 Laravel 开发博客应用系列 —— 设置 Windows 本地开发环境
1.安装原生PHP 下载/解压 PHP 到 PHP 下载页下载最新版本的 PHP(如果使用 Laravel 5.1 的话需要 PHP 5.5.9+ 版本),解压下载的zip格式压缩文件到本地目录,比如 ...
- 基于Laravel开发博客应用系列 —— 十分钟搭建博客系统
1.创建文章数据表及其模型(0:00~2:30) 我们已经在上一节中为博客项目完成了大部分准备工作,现在首先要做的就是为这个项目创建一个新的文章表 posts及该表对应的模型类 Post,使用如下Ar ...
随机推荐
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第七部分(Page 12)
编写你的第一个 Django app,第七部分(Page 12)转载请注明链接地址 本节教程承接第六部分(page 11)的教程.我们继续开发 web-poll应用,并专注于自定义django的自动生 ...
- Angular5基本入门
基本环境安装 首先,确定安装了nodejs与npm,angular 5要求node版本在6.9.x以上.npm版本在 3.x.x以上: 1.安装@angular/cli npm install -g ...
- 不可不看!CSS3中三十一种选择器用法
原文 The 30 CSS Selectors you Must Memorize 由 Jeffrey Way 发表于 2012 年 6 月,介绍了 30 种最常用的 CSS 选择器用法,多加了一种, ...
- 最小主义:我的Musca桌面环境
我现在有一个非常简单实用的桌面环境了:Musca + conky + trayer. 当然Musca运行时需要dmenu,其实也不是非dmenu不可,据说 dzen 也不错. 我现在用的是dmenu. ...
- 渐变色之location概念.
CHENYILONG Blog 渐变色之location概念.全屏幕13-12-22 上午10:18 © chenyilong. Powered by Postach.io Blog
- 【leetcode 简单】 第九十七题 快乐数
写一个程序,输出从 1 到 n 数字的字符串表示. 1. 如果 n 是3的倍数,输出“Fizz”: 2. 如果 n 是5的倍数,输出“Buzz”: 3.如果 n 同时是3和5的倍数,输出 “FizzB ...
- HDU 5532 Almost Sorted Array (最长非递减子序列)
题目链接 Problem Description We are all familiar with sorting algorithms: quick sort, merge sort, heap s ...
- 莫队-小Z的袜子
----普通莫队 首先清楚概率怎么求假设我们要求从区间l到r中拿出一对袜子的概率sum[i]为第i种袜子在l到r中的数量 $$\frac{\sum_{i=l}^{r} {[sum[i] \times ...
- 系统学习(javascript)_基础(数据类型一)
五种基本数据类型:Number,String,Boolean,Null,Undefind: 三种引用数据类型:Object,Array,Symbol: Symbol为ECMAScript6新增的数据类 ...
- ntpdate[35450]: the NTP socket is in use, exiting
当前主机已是NTP服务器,需关闭当前NTP服务,再同步其他NTP服务器的时间 service ntpd stop 然后ps -ef | grep ntp看进程是否已杀掉 然后再次ntpdate Ser ...