教程源于:Laravel学院

继文件上传后呢,咱来搞一搞文章的事情。


1 更改数据表

我们需要改改数据表的结构 因为涉及到重命名列名 所以咱需要引入一个包:Doctrine:

composer require "doctrine/dbal"

1.1 新建迁移文件

php artisan make:migration restructure_posts_table --table=posts

1.2 编辑迁移文件

class RestructurePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('posts', function (Blueprint $table) {
// 在title字段后添加subtitle 文章的副标题
$table->string('subtitle')->after('title');
// 把content改为content_raw Markdown格式的文本
$table->renameColumn('content', 'content_raw');
// 在content字段后添加content_html 使用 Markdown 编辑内容但同时保存 HTML 版本
$table->text('content_html')->after('content');
// 在content_html字段后添加page_image 文章使用到缩略图
$table->string('page_image')->after('content_html');
// 在page_image字段后添加meta_description 文章说明
$table->string('meta_description')->after('page_image');
// 在meta_description字段后添加is_draft 是否是草稿
$table->boolean('is_draft')->after('meta_description');
// 在is_draft字段后添加layout 并设置默认值 使用的布局
$table->string('layout')->after('is_draft')->default('blog.layouts.post');
});
} /**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('subtitle');
$table->dropColumn('content_html');
$table->dropColumn('page_image');
$table->dropColumn('meta_description');
$table->dropColumn('is_draft');
$table->dropColumn('layout');
$table->renameColumn('content_raw', 'content');
});
}
}

1.3 运行迁移

运行命令后看眼数据库是否已经修改成功:

php artisan migrate   

2 和Tag关联

文章和标签是多对多的关系,所以先创建迁移文件,然后记得运行迁移:

class CreatePostTagPivot extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('post_tag_pivot', function (Blueprint $table) {
$table->increments('id');
$table->integer('tag_id')->unsigned()->index();
$table->integer('post_id')->unsigned()->index();
});
} /**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('post_tag_pivot');
}
}

2.1 编辑Tag模型

class Tag extends Model
{
protected $fillable = ['tag', 'title', 'subtitle', 'page_image', 'meta_description', 'layout', 'reverse_direction']; // 定义关系
public function posts()
{
return $this->belongsToMany(Post::class, 'post_tag_pivot');
} /**
* 批量创建需要的tag
*
* @param array $tags
*/
public static function addNeededTags(array $tags)
{
if (count($tags) === 0){
return;
} // 通过tag字段在$tags数组中查找,把找到的模型通过lists来获取所有的tag字段
$found = static::WhereIn('tag', $tags)->lists('tag')->all(); foreach (array_diff($tags, $found) as $tag) {
// 把不存在的tag进行创建 其他字段先自动填充
static::create([
'tag' => $tag,
'title' => $tag,
'subtitle' => 'Subtitle for '.$tag,
'page_image' => '',
'meta_description' => '',
'reverse_direction' => false,
]);
}
}
}

3 展示文章

我们一步步的来,首先先来展示我们的文章吧。

3.1 修改PostController的index方法

    public function index()
{
return view('admin.post.index')->withPosts(Post::all());
}

3.2 修改post/index.blade.php

@extends('admin.layout')

@section('content')
<div class="container-fluid">
<div class="row page-title-row">
<div class="col-md-6">
<h3>Post <small> >> Listing</small></h3>
</div>
<div class="col-md-6 text-right">
<a href="/admin/post/create" class="btn btn-success btn-md">
<i class="fa fa-plus-circle"></i> New Post
</a>
</div>
</div> <div class="row">
<div class="col-sm-12">
@include('admin.partials.error')
@include('admin.partials.success') <table id="posts-table" class="table table-bordered table-striped">
<thead>
<tr>
<td>Published</td>
<td>Title</td>
<td>Subtitle</td>
<td data-sortable="false">Published</td>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td data-order="{{ $post->published_at->timestamp }}">
{{ $post->published_at->format('j-M-y g:ia') }}
</td>
<td>{{ $post->title }}</td>
<td>{{ $post->subtitle }}</td>
<td>
<a href="/admin/post/{{ $post->id }}/edit" class="btn btn-xs btn-info">
<i class="fa fa-edit"></i> Edit
</a>
<a href="/blog/{{ $post->slug }}" class="btn btn-xs btn-warning">
<i class="fa fa-eye"></i> View
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endsection @section('scripts')
<script>
$(function () {
$("#posts-table").DataTable({
order: [[0, "desc"]]
});
});
</script>
@endsection

4 创建文章

4.1 编辑create方法

    public function create()
{
$data = $this->dispatch(new PostFormFields());
return view('admin.post.create', $data);
}

在上面的代码中我们使用到了一个任务,这个任务就是返回每个字段的默认值

4.2 创建Job

创建create方法中用到的job:

php artisan make:job PostFormFields

在app/Jobs中找到刚刚创建的job编辑如下:

class PostFormFields extends Job implements SelfHandling
{
protected $id; protected $fieldList = [
'title' => '',
'subtitle' => '',
'page_image' => '',
'content' => '',
'meta_description' => '',
'is_draft' => "0",
'publish_date' => '',
'publish_time' => '',
'layout' => 'blog.layouts.post',
'tags' => [],
]; /**
* Create a new job instance.
*
* @return void
*/
public function __construct($id = null)
{
$this->id = $id;
} /**
* Execute the job.
*
* @return void
*/
public function handle()
{
$fields = $this->fieldList;
if ($this->id){
$fields = $this->fieldsFromModel($this->id, $fields);
} else {
$when = Carbon::now()->addHour();
$fields['publish_date'] = $when->format('M-j-Y');
$fields['publish_time'] = $when->format('g:i A');
}
foreach ($fields as $fieldName => $fieldValue) {
$fields[$fieldName] = old($fieldName, $fieldValue);
}
return array_merge($fields, ['allTags' => Tag::lists('tag')->all()]);
} /**
* 取出模型中的数据
*
* @param $id
* @param array $fields
* @return array
*/
protected function fieldsFromModel($id, array $fields)
{
$post = Post::findOrFail($id);
$fieldNames = array_keys(array_except($fields, ['tags']));
$fields = ['id' => id];
foreach ($fieldNames as $field) {
$fields[$field] = $post->$field;
}
$fields['tags'] = $post->tags()->lists('tag')->all(); return $fields;
}
}

4.3 添加方法到Post模型

在job中我们使用了publishe_date和time,我们来实现这些get:

    /**
* 设置ContentRaw的同时设置ContentHTML。
*
* @param $value
*/
public function setContentRawAttribute($value)
{
$this->attributes['content_raw'] = $value;
$this->attributes['content_html'] = Markdown::convertToHtml($value);
} /**
* 使用content快捷的返回content_raw
*
* @param $value
* @return mixed
*/
public function getContentAttribute($value)
{
return $this->content_raw;
} /**
* 快捷返回publish_time
*
* @param $value
* @return mixed
*/
public function getPublishTimeAttribute($value)
{
return $this->published_at->format('g:i A');
} /**
* 快捷返回publish_date
*
* @param $value
* @return mixed
*/
public function getPublishDateAttribute($value)
{
return $this->published_at->format('M-j-Y');
}

4.4 下载需要用到的两个前端资源

我们在create视图中需要用到两个前端资源:Selectize.js(下拉列表功能)和Pickadate.js(日期插件),我们来使用Bower下载:

bower install selectize --save
bower install pickadate --save

使用Gulp来整理前端资源:

var gulp = require('gulp');
var rename = require('gulp-rename');
var elixir = require('laravel-elixir'); /*
|--------------------------------------------------------------------------
| Elixir Asset Management
|--------------------------------------------------------------------------
|
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
| for your Laravel application. By default, we are compiling the Less
| file for our application, as well as publishing vendor resources.
|
*/ /**
* 拷贝操作
*/
gulp.task("copyfiles", function(){
// js
gulp.src("vendor/bower_dl/jquery/dist/jquery.js")
.pipe(gulp.dest("resources/assets/js/"));
// bootstrap
gulp.src("vendor/bower_dl/bootstrap/less/**")
.pipe(gulp.dest("resources/assets/less/bootstrap"));
gulp.src("vendor/bower_dl/bootstrap/dist/js/bootstrap.js")
.pipe(gulp.dest("resources/assets/js/"));
// font 不用编译和合并 直接复制到public就可以
gulp.src("vendor/bower_dl/bootstrap/fonts/**")
.pipe(gulp.dest("public/assets/fonts")); // awesome
gulp.src("vendor/bower_dl/font-awesome/less/**")
.pipe(gulp.dest("resources/assets/less/fontawesome")); gulp.src("vendor/bower_dl/font-awesome/fonts/**")
.pipe(gulp.dest("public/assets/fonts")); // 拷贝 datatables
var dtDir = 'vendor/bower_dl/datatables.net-plugins/integration/'; gulp.src("vendor/bower_dl/datatables/media/js/jquery.dataTables.js")
.pipe(gulp.dest('resources/assets/js/')); gulp.src(dtDir + 'bootstrap/3/dataTables.bootstrap.css')
.pipe(rename('dataTables.bootstrap.less'))
.pipe(gulp.dest('resources/assets/less/others/')); gulp.src(dtDir + 'bootstrap/3/dataTables.bootstrap.js')
.pipe(gulp.dest('resources/assets/js/')); // 拷贝selectize
gulp.src("vendor/bower_dl/selectize/dist/css/**")
.pipe(gulp.dest("public/assets/selectize/css"));
gulp.src("vendor/bower_dl/selectize/dist/js/standalone/selectize.min.js")
.pipe(gulp.dest("public/assets/selectize/")); // 拷贝 pickadate
gulp.src("vendor/bower_dl/pickadate/lib/compressed/themes/**")
.pipe(gulp.dest("public/assets/pickadate/themes/")); gulp.src("vendor/bower_dl/pickadate/lib/compressed/picker.js")
.pipe(gulp.dest("public/assets/pickadate/")); gulp.src("vendor/bower_dl/pickadate/lib/compressed/picker.date.js")
.pipe(gulp.dest("public/assets/pickadate/")); gulp.src("vendor/bower_dl/pickadate/lib/compressed/picker.time.js")
.pipe(gulp.dest("public/assets/pickadate/"));
}); elixir(function(mix) { // 合并脚本文件
mix.scripts([
'js/jquery.js',
'js/bootstrap.js',
'js/jquery.dataTables.js',
'js/dataTables.bootstrap.js'
],
'public/assets/js/admin.js',
'resources/assets'
); // 编译 Less
mix.less('admin.less', 'public/assets/css/admin.css');
});

运行Gulp:

gulp copyfiles
gulp

4.5 创建create视图

@extends("admin.layout")
{{-- 样式表 --}}
@section('styles')
<link rel="stylesheet" href="/assets/selectize/css/selectize.css">
<link rel="stylesheet" href="/assets/selectize/css/selectize.bootstrap3.css">
<link rel="stylesheet" href="/assets/pickadate/themes/default.css">
<link rel="stylesheet" href="/assets/pickadate/themes/default.date.css">
<link rel="stylesheet" href="/assets/pickadate/themes/default.time.css">
@endsection
{{--content--}}
@section("content")
<div class="container-fluid">
<div class="row page-title-row">
<div class="col-md-12">
<h3>Posts <small> >> Add New Post</small></h3>
</div>
</div> <div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">New Post Form</h3>
</div>
<div class="panel-body"> @include('admin.partials.error') <form action="{{ route("admin.post.store") }}" method="POST" class="form-horizontal">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
@include('admin.post._form')
<div class="col-md-8">
<div class="form-group">
<div class="col-md-10 col-md-offset-2">
<button class="btn btn-primary btn-lg" type="submit">
<i class="fa fa-disk-o"></i>
Save New Post
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
{{--scripts--}}
@section('scripts')
<script src="/assets/pickadate/picker.js"></script>
<script src="/assets/pickadate/picker.date.js"></script>
<script src="/assets/pickadate/picker.time.js"></script>
<script src="/assets/selectize/selectize.min.js"></script>
<script>
$(function() {
$("#publish_date").pickadate({
format: "mmm-d-yyyy"
});
$("#publish_time").pickatime({
format: "h:i A"
});
$("#tags").selectize({
create: true
});
});
</script>
@endsection

创建我们在上面用到的_form.blade.php:

<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="title" class="col-md-2 control-label">
Title
</label>
<div class="col-md-10">
<input type="text" class="form-control" name="title" autofocus id="title" value="{{ $title }}">
</div>
</div>
<div class="form-group">
<label for="subtitle" class="col-md-2 control-label">
Subtitle
</label>
<div class="col-md-10">
<input type="text" class="form-control" name="subtitle" id="subtitle" value="{{ $subtitle }}">
</div>
</div>
<div class="form-group">
<label for="page_image" class="col-md-2 control-label">
Page Image
</label>
<div class="col-md-10">
<div class="row">
<div class="col-md-8">
<input type="text" class="form-control" name="page_image" id="page_image" onchange="handle_image_change()" alt="Image thumbnail" value="{{ $page_image }}">
</div>
<script>
function handle_image_change() {
$("#page-image-preview").attr("src", function () {
var value = $("#page_image").val();
if ( ! value) {
value = {!! json_encode(config('blog.page_image')) !!};
if (value == null) {
value = '';
}
}
if (value.substr(0, 4) != 'http' && value.substr(0, 1) != '/') {
value = {!! json_encode(config('blog.uploads.webpath')) !!} + '/' + value;
}
return value;
});
}
</script>
<div class="visible-sm space-10"></div>
<div class="col-md-4 text-right">
<img src="{{ page_image($page_image) }}" class="img img_responsive" id="page-image-preview" style="max-height:40px">
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="content" class="col-md-2 control-label">
Content
</label>
<div class="col-md-10">
<textarea class="form-control" name="content" rows="14" id="content">{{ $content }}</textarea>
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="publish_date" class="col-md-3 control-label">
Pub Date
</label>
<div class="col-md-8">
<input class="form-control" name="publish_date" id="publish_date" type="text" value="{{ $publish_date }}">
</div>
</div>
<div class="form-group">
<label for="publish_time" class="col-md-3 control-label">
Pub Time
</label>
<div class="col-md-8">
<input class="form-control" name="publish_time" id="publish_time" type="text" value="{{ $publish_time }}">
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-3">
<div class="checkbox">
<label>
<input {{ checked($is_draft) }} type="checkbox" name="is_draft">
Draft?
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="tags" class="col-md-3 control-label">
Tags
</label>
<div class="col-md-8">
<select name="tags[]" id="tags" class="form-control" multiple>
@foreach ($allTags as $tag)
<option @if (in_array($tag, $tags)) selected @endif value="{{ $tag }}">
{{ $tag }}
</option>
@endforeach
</select>
</div>
</div>
<div class="form-group">
<label for="layout" class="col-md-3 control-label">
Layout
</label>
<div class="col-md-8">
<input type="text" class="form-control" name="layout" id="layout" value="{{ $layout }}">
</div>
</div>
<div class="form-group">
<label for="meta_description" class="col-md-3 control-label">
Meta
</label>
<div class="col-md-8">
<textarea class="form-control" name="meta_description" id="meta_description" rows="6">{{ $meta_description }}</textarea>
</div>
</div>
</div>
</div>

上面使用到了一个帮助函数,我们在helper.php中添加这个方法:

/**
* 如果传进来的参数是true 则返回checked,false放回空字符串。
*
* @param $value
* @return string
*/
function checked($value)
{
return $value ? 'checked' : '';
} /**
* Return img url for headers
*/
function page_image($value = null)
{
if (empty($value)) {
$value = config('blog.page_image');
}
if (! starts_with($value, 'http') && $value[0] !== '/') {
$value = config('blog.uploads.webpath') . '/' . $value;
} return $value;
}

4.6 创建表单请求类

class PostCreateRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
} /**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required',
'subtitle' => 'required',
'content' => 'required',
'publish_date' => 'required',
'publish_time' => 'required',
'layout' => 'required',
];
} /**
* 返回创建模型所需要用的数据。
*
* @return array
*/
public function postFillData()
{
$published_at = new Carbon(
$this->publish_date.' '.$this->publish_time
);
return [
'title' => $this->title,
'subtitle' => $this->subtitle,
'page_image' => $this->page_image,
'content_raw' => $this->get('content'),
'meta_description' => $this->meta_description,
'is_draft' => (bool)$this->is_draft,
'published_at' => $published_at,
'layout' => $this->layout,
];
}
}

4.7 实现store方法

    public function store(Requests\PostCreateRequest $request)
{
$post = Post::create($request->postFillData());
$post->syncTags($request->get('tags', [])); return redirect()
->route('admin.post.index')
->withSuccess('New Post Successfully Created.');
}

4.8 实现syncTags方法

在store方法中使用了Post模型的syncTags方法 用于同步标签,在Post模型中创建这个方法:

    public function syncTags(array $tags)
{
Tag::addNeededTags($tags); if (count($tags)){
$this->tags()->sync(Tag::whereIn('tag', $tags)->lists('id')->all());
return;
}
$this->tags()->detach();
}

4.9 实现store方法

现在我们可以实现PostController上的store方法了:

    public function store(Requests\PostCreateRequest $request)
{
$post = Post::create($request->postFillData());
$post->syncTags($request->get('tags', [])); return redirect()
->route('admin.post.index')
->withSuccess('New Post Successfully Created.');
}

5 更新Post

5.1 创建edit视图

@extends('admin.layout')

@section('styles')
<link href="/assets/pickadate/themes/default.css" rel="stylesheet">
<link href="/assets/pickadate/themes/default.date.css" rel="stylesheet">
<link href="/assets/pickadate/themes/default.time.css" rel="stylesheet">
<link href="/assets/selectize/css/selectize.css" rel="stylesheet">
<link href="/assets/selectize/css/selectize.bootstrap3.css" rel="stylesheet">
@stop @section('content')
<div class="container-fluid">
<div class="row page-title-row">
<div class="col-md-12">
<h3>Posts <small>» Edit Post</small></h3>
</div>
</div> <div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Post Edit Form</h3>
</div>
<div class="panel-body"> @include('admin.partials.error')
@include('admin.partials.success') <form class="form-horizontal" role="form" method="POST" action="{{ route('admin.post.update', $id) }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="PUT"> @include('admin.post._form') <div class="col-md-8">
<div class="form-group">
<div class="col-md-10 col-md-offset-2">
<button type="submit" class="btn btn-primary btn-lg" name="action" value="continue">
<i class="fa fa-floppy-o"></i>
Save - Continue
</button>
<button type="submit" class="btn btn-success btn-lg" name="action" value="finished">
<i class="fa fa-floppy-o"></i>
Save - Finished
</button>
<button type="button" class="btn btn-danger btn-lg" data-toggle="modal" data-target="#modal-delete">
<i class="fa fa-times-circle"></i>
Delete
</button>
</div>
</div>
</div> </form> </div>
</div>
</div>
</div> {{-- 确认删除 --}}
<div class="modal fade" id="modal-delete" tabIndex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
×
</button>
<h4 class="modal-title">Please Confirm</h4>
</div>
<div class="modal-body">
<p class="lead">
<i class="fa fa-question-circle fa-lg"></i>
Are you sure you want to delete this post?
</p>
</div>
<div class="modal-footer">
<form method="POST" action="{{ route('admin.post.destroy', $id) }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="DELETE">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-danger">
<i class="fa fa-times-circle"></i> Yes
</button>
</form>
</div>
</div>
</div>
</div>
</div> @stop @section('scripts')
<script src="/assets/pickadate/picker.js"></script>
<script src="/assets/pickadate/picker.date.js"></script>
<script src="/assets/pickadate/picker.time.js"></script>
<script src="/assets/selectize/selectize.min.js"></script>
<script>
$(function() {
$("#publish_date").pickadate({
format: "mmm-d-yyyy"
});
$("#publish_time").pickatime({
format: "h:i A"
});
$("#tags").selectize({
create: true
});
});
</script>
@stop

5.2 生成edit方法

我们创建好edit视图后要生成对应的方法:PostController下的edit方法。

    public function edit($id)
{
$data = $this->dispatch(new PostFormFields($id));
return view('admin.post.edit', $data);
}

5.3 创建修改用的Request

php artisan make:request PostUpdateRequest

我们的修改用的Request和创建用的Request很相像,所以直接继承就好:

class PostUpdateRequest extends PostCreateRequest
{ }

5.4 编辑update方法

    public function update(Requests\PostUpdateRequest $request, $id)
{
$data = $request->postFillData();
$post = Post::findOrFail($id);
$post->fill($data);
$post->save();
$post->syncTags($request->get('tags', [])); if ($request->get('action') === 'continue'){
return redirect()->back()->withSuccess('Post saved.');
} return redirect()->route('admin.post.index')->withSuccess('Post saved.');
}

6 删除Post

修改destroy方法:

    public function destroy($id)
{
$post = Post::findOrFail($id);
// 删除中间表的数据。
$post->tags()->detach();
$post->delete(); return redirect()
->route('admin.post.index')
->withSuccess('Post deleted.');
}

Laravel5.1 搭建博客 --文章的增删改查的更多相关文章

  1. 夺命雷公狗---Thinkphp----12之文章的增删改查(图片上传和关联查询)

    我们由于表分析的不够完善,所以我们来加多一个tid的字段,到时候主要目的是为了更好的遍历出文章是属于那个分类下的,表如下所示: 那么下一步我们就开始创建一个ArticleController.clas ...

  2. Laravel5.1 搭建博客 --编译前端文件

    上篇文章写了Gulp编译前端文件,这篇记录下在搭建博客中使用Gulp 1 引入bootstrap和js 1.1 首先先在项目本地安装Bower sudo npm install bower 1.2 创 ...

  3. Laravel5.1 搭建博客 --展示简单的首页

    今天起开始搭建博客,把之前学的东西运用下. 1 创建 配置项目 1.1 创建项目 composer create-project laravel/laravel blog 5.1.1 1.2 配置数据 ...

  4. .net core项目搭建swagger接口实现简单增删改查

    .net core搭建swagger 1,新建立.net core项目(这里不再细说) 2,引入NuGet程序包 3,建立项目之后在Startup类中配置swagger 这里我直接把代码贴出来: 在C ...

  5. Laravel5.1 搭建博客 --构建标签

    博客的每篇文章都是需要有标签的,它与文章也是多对多的关系 这篇笔记也是记录了实现标签的步骤逻辑. 在我们之前的笔记中创建了Tag的控制器和路由了 所以这篇笔记不在重复 1 创建模型与迁移文件 迁移文件 ...

  6. Django搭建博客文章---模型层

    页面展示所需字段 1.文章标题---文本类型 2.文章摘要---文本类型 3.文章内容--文本类型 4.唯一的ID标记---int数字类型(自增.主键) 5.发布日期--日期类型 模型层定义字段 1. ...

  7. Laravel5.1 搭建博客 --后台登录

    今天咱来实现后台的登录. 首先我们的后台需要三个控制器: PostController:管理文章. TagController:管理文章标签. UploadController:上传文件. 当我们访问 ...

  8. Laravel5.1 搭建博客 --上传文件及文件管理

    教程源自:Laravel学院 这一节 咱来说说上传文件的功能实现,我们会把上传的文件保存到项目本地,不仅上传 还有删除和预览功能. 1 配置 我们先从配置开始做起,先修改我们自己创建的 blog.ph ...

  9. 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查

    上一篇文章(https://www.cnblogs.com/meowv/p/12913676.html)我们用Code-First的方式创建了博客所需的实体类,生成了数据库表,完成了对EF Core的 ...

随机推荐

  1. xUtils中用DbUtils,ViewUtils的用法

    一.有关xUtils的简介 xUtils 包含了很多实用的android工具.xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10 ...

  2. mysql允许远程连接

    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;

  3. Web应用程序项目OxiteSite已配置为使用IIS.在本地计算机上找不到服务器

    今天还是没事干(我的博客还想都是以这句话开始的),看看小组里边的文章Oxite初探.下载Oxite的41500版本,打开后遇到这样的问题.如下图所示 解决方法: 1.邮件点击OxiteSite项目,选 ...

  4. 我的SpringMvc学习之路之注解

    用注解取代配置文件可降低编程是不必要的麻烦和错误. @Controller  控制器定义 在一个class的上面写上@controller声明此类为控制器类.在配置中*.dispatcher.xml里 ...

  5. C# 之 FTPserver中文件上传与下载(一)

            近期接手这样一个文件上传到ftpserver的一个功能,接下来就给大家解析一下这一功能. 首先,今天我们要讲的是怎么创建一个FTPserver. 1.首先我们创建一个用户,当然不想创建 ...

  6. Python partition() 方法

    描述 Python partition() 方法用来根据指定的分隔符将字符串进行分割. 如果字符串包含指定的分隔符,则返回一个3元的元组,第一个为分隔符前面的子字符串,第二个为分隔符本身,第三个为分隔 ...

  7. hibernate开发流程

    开发流程,注意:每个hibernate版本在集成的时候是不太一样的.本次使用的是hibernate-distribution-3.6.10.Final-dist 一.开发流程 1)在数据库中创建表,代 ...

  8. AESDK AE中层类型的3种取得方式

    有一部分属于类型标志,比如调节层,空对象层.用mSuites->LayerSuite7()->AEGP_GetLayerFlags去取 而灯光,文字这些信息,直接取类型即可 mSuites ...

  9. hdoj 4526 威威猫系列故事——拼车记

    威威猫系列故事——拼车记 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  10. 一款jquery和css3实现的卡通人物动画特效

    之前为大家分享了很多jquery和css3的动画实例.今天给大家带来一款非常炫的jquery和css3实现的卡通人物动画特效.效果图如下: 在线预览   源码下载 实现的代码. html代码: < ...