Build a naïve Blog with Laravel




  • *前端layui
  • *springboot通用开发流程
  • springmvc
  • hibernate-jpa
  • web-service-dal
  • mustache模板引擎
  • *Springboot Interceptor开发
  • *富文本编辑器 simeditor
  • *博客热词词云
  • *图片上传组件 及解决方案
  • 前端layui.upload
  • spring文件上传支持
  • ng代理/tomcat vdir
  • 图像处理
  • *EXIF 读取及记录
  • 百度图像识别API 获取信息及记录
  • *图像timeline展示
  • 部署相关
  • spring-boot的打包
  • linux基本命令
  • 部署依赖(JDK、MySQL、ng)


day2spring interceptor开发完成登录的interceptor开发
day5-6图片上传组件 及解决方案完成相册页

For log propose, do not follow steps below in production project.

From 2019/01/04 ~ 2019/01/11 ChinaSofti software development, the final goal is to design a blog system.

The whole system can be describe as below:

User Consideration

The Admin User will be the only person has the permission to Add/Edit/Delete Post, Add/Edit/Delete Post, the normal user has only the permission to post comment.

Comment Consideration

The Comments has no in-line reply function as the comments for one post is just listed at date ascend.(Single foreign key referring the post’s primary key.)

Post Consideration

For better editing the pages, and the support rich-content requisite, Markdown is used to store post content, on-the-fly Markdown to HTML rendering is needed for displaying the content for end user.

The primary key for post will be UUID (without slashes), so the post URL style will look like : /posts/ad65b02b1e6c4ea1ba7af94f69aeec1f/ which is way better than the /posts/2.

For this need, we need to import the UUID repo, as below:

composer require webpatser/laravel-uuid

Since our DB stores the Markdown data, we will need to use a Class to convert Markdown formatted text to HTML for front-end rendering.

composer require graham-campbell/markdown

Register them in config/app.php :

'Uuid' => Webpatser\Uuid\Uuid::class,
'Markdown' => GrahamCampbell\Markdown\Facades\Markdown::class,

In related controllers(such as app/Http/Controllers/PostController.php), use the needed package:

use GrahamCampbell\Markdown\Facades\Markdown;

Init the Laravel Project

laravel new laralog

and fill it with default user authentication system.

php artisan make:auth

then use php artisan serve for open a dev server at localhost:8000, this should look like as below.


Since this is only a blog, we don’t need specified routing system, just hard-code the page route in route.php and the rest of the posts can be accessed by /posts/{post_id} which should be controlled by PostController.

As CRUD for blog post, we define the following RESTful design pattern.

GET/posts/{post_uuid}Display the specified post content.
GET/posts/{post_uuid}/editDisplay the editor for specified post.
DELETE/posts/{post_uuid}Delete the specified post.(Soft Delete)
POST/postsCreate a post.
PUT/posts/{post_uuid}As an interface for receiving JSON formatted post content.

We define the post route here, let’s create PostController first with php artisan make:controller PostController:


Pages routing will be hard-coded (About page as example):


In app/Http/Controllers/PostController.php:

    public function index()
        return view('about');

Build User Seed along with some DB tables

User migration, user should login with email and password:

        Schema::create('users', function (Blueprint $table) {

Create the Model with Post migration:

php artisan make:model Post
php artisan make:migration create_blog_post

Post Model (app/Post.php):

class Post extends Model
    protected $table = 'post';

Post migration(database/migrations/2019_01_05_014913_create_blog_post.php):

      Schema::create('posts', function (Blueprint $table) {

Create Post Seeder:

php artisan make:seeder PostSeeder

In database/seeds/PostSeeder.php:

    public function run()
        for ($i=1; $i < 10; $i++) {
          'post_uuid' => (string) Uuid::generate(4),
          'post_title' => str_random(20),
          'post_type' => "post",
          'post_content' => str_random(300),
        'post_uuid' => (string) Uuid::generate(4),
        'post_title' => str_random(20),
        'post_type' => "gallery",
        'post_content' => "![bird-3732867_1920.jpg](",

Since there is only one Admin, we will need to insert the Admin user on migration seed section:

php artisan make:seeder UserSeeder

in database/seeds/UserSeeder.php we define our Admin user here:

    public function run()
        'name' => "Nova Kwok",
        'role' => "admin",
        'email' => "",
        'password' => bcrypt("opennova"),

Here comes the comment part, as I mentioned above, Post -> Comment has a One-To-Many relation, there is a need to declare the “foreign key” in the migration file, in database/migrations/2019_01_06_060322_create_comments.php.

        Schema::create('comments', function (Blueprint $table) {

Run the seeds to seed the DB:

php artisan db:seed --class=UserSeeder
php artisan db:seed --class=PostSeeder

Index Page Blade


<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">

          @foreach ($all_posts as $key => $post)
            <div class="card">
                <div class="card-header"><a href="/posts/{{ $post->post_uuid }}">{{ $post->post_title }}</a></div>
                <div class="card-body">
                    {{ $post->post_content }}

        <div class="col-md-4">
          <div class="card">
              <div class="card-header">TukiBlog</div>
              <div class="card-body">
                    <li><a href="/login">Login</a></li>
                    <li><a href="/register">Register</a></li>
                    <li><a href="">Nova Kwok's Blog</a></li>
                    <li><a href="htt[ps://">Keshane's Blog</a></li>
          <div class="card">
              <div class="card-header">Pages</div>
              <div class="card-body">
                    <li><a href="/about">About</a></li>
          <div class="card">
              <div class="card-header">Pages</div>
              <div class="card-body">
                    <li><a href="/about">About</a></li>

Adding the Post_edit Page with Editor

HTML Part:

          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text" id="">Post Title</span>
            <input type="text" name="post_title" class="form-control" value="{{ $post->post_title }}">

            <div class="card">
                <div class="card-body">
                  <small>The Post URL will be: <a href="/posts/{{ $post->post_uuid }}">/posts/{{ $post->post_uuid }}</a> </small>

                  <form class="" action="/posts/{{ $post->post_uuid }}" method="POST" enctype="multipart/form-data">
                        <textarea id="md-text" name="post_content" rows="8">{{ $post->post_content }}</textarea> <div class="row justify-content-center"> <div class="col-lg-6 col-sm-6 col-xs-12"> <button class="btn btn-block btn-raised btn-success pull-right" input type="submit">Edit</button> </div> </div> </form> </div> </div>

Adding the SimpleMDE Editor:

<link rel="stylesheet" href="">
  <script src=""></script> <script type="text/javascript"> var simplemde = new SimpleMDE({ element: document.getElementById("md-text"), toolbar: ["table", "heading", "|", "preview"] });

Defining the Middleware & Securing the Route

Create a middleware as guard for guarding the Admin Panel.

php artisan make:middleware IsAdmin

In app/Http/Middleware/IsAdmin.php

    public function handle($request, Closure $next)
        $role = auth()->user()->role;
        if($role != "admin")
            return response()->view('errors.403');
        return $next($request);

And register it in the Kernel(app/Http/Kernel.php):

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'admin' => \App\Http\Middleware\IsAdmin::class,

Applying Middleware to the protected route (routes/web.php) so when a non-admin user tries to visit protected page will meet an 403 error.



Laravel has provide a simple pagination function, we define pagination in the index function:

    public function index($page = 1)
        $all_posts = Post::paginate(5);
        $post = Post::paginate(5);
        $pre_url =  $post->previousPageUrl();
        $next_url =  $post->nextPageUrl();
        return view('index')

And in the resources/views/index.blade.php, we define the following front-end.

            <ul class="pagination">
              <li class="page-item"><a class="page-link" href="{{ $pre_url }}">Previous</a></li>
              <li class="page-item"><a class="page-link" href="{{ $next_url }}">Next</a></li>