按照视频和老师讲解,实现一个简易的CMS。
软件:PHPStorm、Laragon、Google Chrome
—😄-------------😛 -------------😃-------------😄-------------😛 -------------😃-------------😛 -------------😃—
前文链接:
#点此处查看过程记录1的内容#
#点此处查看过程记录2的内容#
目录
4.4 添加日期选择器和内容的文字样式编辑器
4.4.1 引入文字样式编辑器需要的js和css
- 在post/create.blade.php末尾引入trix的js网址
- 在总布局页面添加一个css占位符
- 在post/create.blade.php中引入css
4.4.2 添加编辑器的样式代码,且引用他的JavaScript
- 更改post/create.blade.php中内容的布局
<div class="form-group">
<label for="content">内容:</label>
<input id="content" type="hidden" name="content" class="form-control">
<trix-editor input="content"></trix-editor>
</div>
- 将总布局中script移到我们设置的script占位符的前面
4.4.3 添加发布时间
- 将flatpicker的JavaScript与css引入post/create.blade.php
- 加入一段js代码
<script>
flatpickr('#published_at',{
enableTime:true
})
</script>
-
并添加发布时间的选择框
-
在StorePost.php中添加对发布时间的必填选项
public function rules()
{
return [
'title' => 'required|min:3|max:30|unique:posts' ,
'description' =>'required' ,
'content' =>'required' ,
'image' =>'required|image' ,
'category_id' =>'required',
'published_at'=>'required'
];
}
4.4.4效果展示
4.5 实现编辑文章效果
- 修改控制器中edit()内的代码
public function edit(Post $post)
{
//
$categories = Category::all();
return view('posts.create',compact('categories','post'));
}
- 修改create布局,使其能够复用
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<strong>
{{isset($post)?'编辑文章':'创建文章'}}
</strong>
</div>
<div class="card-body">
<form action="{{isset($post)?route('posts.update',$post->id):route('posts.store')}}"
method="post" enctype="multipart/form-data">
@csrf
@if(isset($post))
@method('patch')
@endif
<div class="form-group">
<label for="title">文章名称:</label>
<input type="text" name="title" value="{{old('title',isset($post)?$post->title:'')}}"
id="title" class="form-control @error('title') is-invalid @enderror"
placeholder="请输入文章名称....">
@error('title')
<div class="invalid-feedback">
{!! $message !!}
</div>
@enderror
</div>
<div class="form-group">
<label for="description">说明:</label>
<textarea name="description" id="description" cols="30" rows="3"
class="form-control @error('title') is-invalid @enderror"
>{{old('description',isset($post)?$post->description:'')}}</textarea>
@error('description')
<div class="invalid-feedback">
{!! $message !!}
</div>
@enderror
</div>
<div class="form-group">
<label for="content">内容:</label>
<input id="content" type="hidden" name="content" class="form-control"
value="{{isset($post)?$post->content:''}}">
<trix-editor input="content"></trix-editor>
</div>
<div class="form-group">
<label for="published_at">发表日期:</label>
<input id="published_at" type="text" name="published_at" class="form-control"
value="{{isset($post)?$post->published_at:''}}">
</div>
<div class="form-group">
<label for="category_id">分类:</label>
<select name="category_id" id="category_id"
class="form-control @error('title') is-invalid @enderror">
@foreach($categories as $category)
<option value="{{$category->id}}
@if(old('category_id',isset($post)?$post->content:'')==$category->id) selected @endif">
{{$category->name}}
</option>
@endforeach
</select>
@error('category_id')
<div class="invalid-feedback">
{!! $message !!}
</div>
@enderror
</div>
@if(isset($post))
<div class="form-group">
<img src="{{asset($post->image)}}" alt="" style="width: 100px">
</div>
@endif
<div class="form-group">
<label for="image">海报:</label>
<input type="file" class="form-control-file @error('title') is-invalid @enderror"
name="image" id="image" placeholder="请上传海报图片...">
@error('image')
<div class="invalid-feedback">
{!! $message !!}
</div>
@enderror
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">
{{isset($post)?'更新文章':'创建文章'}}
</button>
</div>
</form>
</div>
</div>
@endsection
@section('script')
<script src="https://cdnjs.cloudflare.com/ajax/libs/trix/1.2.3/trix.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script>
flatpickr('#published_at',{
enableTime:true
})
</script>
@endsection
@section('css')
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/trix/1.2.3/trix.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
@endsection
- 建一个UpdataPost.php,并添加内容
- 更改控制器中的update()
5.效果
4.6 恢复回收站内的文章
1.添加恢复路由,并在postController中添加restore()
2. 修改post/create.blade.php内容
3.效果展示
4.7 建立标签类型
4.7.1 创建Tag模型
1.修改路由
2.创建Tag的模型,并添加表的结构
3.在Tag.php中添加$fillable,使得能够接收到name的信息
4.创建存储和更新Tags的request,并填写数据的要求
5.在视图层建立post的内部视图index.blade.php和创建视图create.blade.php,其代码可参考category的对应视图
6.在总视图层app.blade.php中添加标签这一栏
7.更新表
8.效果展示
4.7.2 写文章是加上标签选项
1.在Post.php中添加标签的联系
2.在Tag.php中建立Post的联系
3.在文章控制器中的edit()和create()中加入tags参数
4.在文章创建页面添加标签选项
5.在post.php中添加hasTag()方法用于查看原文是否有tags,便于之后的修改
4.7.3 给标签加样式
1.进入select2的网址使用他们的样式
2.复制css和js链接到create.blade.php
3.效果
5 自定义home主页
- 将TheSaaS模板包中的theme文件夹拷贝到我们的工程中
- 在 .gitignore 文件中加入这行代码
- 删除之前的welcome.blade.php中的所有内容,并将theme中的index.html代码考入Welcome.blade.php
- 将theme文件中我们需要的文件和图片拷贝到public中
- 修改welcome.blade.php中的css、js等的引用链接
<!-- Styles -->
<link href="{{asset('css/page.min.css')}}" rel="stylesheet">
<link href="{{asset('css/style.css')}}" rel="stylesheet">
<!-- Favicons -->
<link rel="apple-touch-icon" href="{{asset('img/apple-touch-icon.png')}}">
<link rel="icon" href="{{asset('img/favicon.png')}}">
<!-- Scripts -->
<script src="{{asset('js/page.min.js')}}"></script>
<script src="{{asset('js/script.js')}}"></script>
- 添加一个PostsTablesSeeder.php 用于存放我们主页的文章
<?php
use App\Post;
use App\Category;
use Illuminate\Database\Seeder;
class PostsTableSeeder extends Seeder
{
public function run()
{
$category1 = Category::create([
'name'=>'News'
]);
$category2 = Category::create([
'name'=>'Partnership'
]);
$category3 = Category::create([
'name'=>'Market'
]);
$post1 =Post::create([
'title'=>'第一个消息',
'description'=>'描述',
'content'=>'内容',
'category_id'=>$category1->id,
'image'=>'public/storage/posts/1.jpg'
]);
$post2 =Post::create([
'title'=>'第二个消息',
'description'=>'描述',
'content'=>'内容',
'category_id'=>$category2->id,
'image'=>'posts/2.jpg'
]);
$post3 =Post::create([
'title'=>'第三个消息',
'description'=>'描述',
'content'=>'内容',
'category_id'=>$category3->id,
'image'=>'posts/3.jpg'
]);
$post4 =Post::create([
'title'=>'第四个消息',
'description'=>'描述',
'content'=>'内容',
'category_id'=>$category3->id,
'image'=>'posts/4.jpg'
]);
}
}
7.修改DatabaseSeeder.php的内容,并migrate一下
8.此时将自动建好刚刚设置的文章和分类
9.建立一个控制主页的controller
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Post;
use Illuminate\Http\Request;
class WelcomeController extends Controller
{
//
public function index()
{
return view('welcome')
->with('categories',Category::all())
->with('posts',Post::all());
}
}
10.更改路由中的设置
此刻返回你的主页,将看到下面的样子
11. 修改主页的布局,使分类和文章联系起来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="keywords" content="">
<title>TheSaaS — Blog with sidebar</title>
<!-- Styles -->
<link href="{{asset('css/page.min.css')}}" rel="stylesheet">
<link href="{{asset('css/style.css')}}" rel="stylesheet">
<!-- Favicons -->
<link rel="apple-touch-icon" href="{{asset('img/apple-touch-icon.png')}}">
<link rel="icon" href="{{asset('img/favicon.png')}}">
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-light navbar-stick-dark" data-navbar="sticky">
<div class="container">
<div class="navbar-left">
<button class="navbar-toggler" type="button">☰</button>
<a class="navbar-brand" href="">
<img class="logo-dark" src="{{asset('img/logo-dark.png')}}" alt="logo">
<img class="logo-light" src="{{asset('img/logo-light.png')}}" alt="logo">
</a>
</div>
<section class="navbar-mobile">
<span class="navbar-divider d-mobile-none"></span>
<ul class="nav nav-navbar">
</ul>
</section>
@if (Route::has('login'))
<div class="top-right links">
@auth
<a class="btn btn-xs btn-round btn-success" href="{{url('/home')}}">我的主页</a>
@else
<div class="d-inline-block">
<a class="btn btn-xs btn-round btn-success" href="{{route('login')}}">登录</a>
@if (Route::has('register'))
<a class="btn btn-xs btn-round btn-light" href="{{route('register')}}">注册</a>
@endif
</div>
@endauth
</div>
@endif
</div>
</nav><!-- /.navbar -->
<!-- Header -->
<header class="header text-center text-white" style="background-image: linear-gradient(-225deg, #5D9FFF 0%, #B8DCFF 48%, #6BBBFF 100%);">
<div class="container">
<div class="row">
<div class="col-md-8 mx-auto">
<h1>欢迎来到我的CMS</h1>
<p class="lead-2 opacity-90 mt-6">Read and get updated on how we progress</p>
</div>
</div>
</div>
</header><!-- /.header -->
<!-- Main Content -->
<main class="main-content">
<div class="section bg-gray">
<div class="container">
<div class="row">
<div class="col-md-8 col-xl-9">
<div class="row gap-y">
@foreach($posts as $post)
<div class="col-md-6">
<div class="card border hover-shadow-6 mb-6 d-block">
<a href="#"><img class="card-img-top" src="{{asset($post->image)}}" alt="Card image cap"></a>
<div class="p-6 text-center">
<p>
<a class="small-5 text-lighter text-uppercase ls-2 fw-400" href="#">
{{$post->category->name}}
</a>
</p>
<h5 class="mb-0">
<a class="text-dark" href="#">
{{$post->title}}
</a>
</h5>
</div>
</div>
</div>
@endforeach
</div>
<nav class="flexbox mt-30">
<a class="btn btn-white disabled"><i class="ti-arrow-left fs-9 mr-4"></i> Newer</a>
<a class="btn btn-white" href="#">Older <i class="ti-arrow-right fs-9 ml-4"></i></a>
</nav>
</div>
<div class="col-md-4 col-xl-3">
<div class="sidebar px-4 py-md-0">
<h6 class="sidebar-title">Search</h6>
<form class="input-group" target="#" method="GET">
<input type="text" class="form-control" name="s" placeholder="Search">
<div class="input-group-addon">
<span class="input-group-text"><i class="ti-search"></i></span>
</div>
</form>
<hr>
<h6 class="sidebar-title">分类</h6>
<div class="row link-color-default fs-14 lh-24">
@foreach($categories as $category)
<div class="col-6">
<a href="#">
{{$category->name}}
</a>
</div>
@endforeach
</div>
<hr>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="row gap-y align-items-center">
<div class="col-6 col-lg-3">
<a href=""><img src="{{asset('img/logo-dark.png')}}" alt="logo"></a>
</div>
<div class="col-6 col-lg-3 text-right order-lg-last">
<div class="social">
<a class="social-facebook" href="https://www.facebook.com/thethemeio"><i class="fa fa-facebook"></i></a>
<a class="social-twitter" href="https://twitter.com/thethemeio"><i class="fa fa-twitter"></i></a>
<a class="social-instagram" href="https://www.instagram.com/thethemeio/"><i class="fa fa-instagram"></i></a>
<a class="social-dribbble" href="https://dribbble.com/thethemeio"><i class="fa fa-dribbble"></i></a>
</div>
</div>
</div>
</div>
</footer><!-- /.footer -->
<!-- Scripts -->
<script src="{{asset('js/page.min.js')}}"></script>
<script src="{{asset('js/script.js')}}"></script>
</body>
</html>
效果展示: