Thứ Năm, 10 tháng 11, 2016

Build a Blog System with Laravel 5.3 - Setup Database, Display Post, Single Page, Comments System, Bootstrap Templates


Laravel 5.3 tutorial - How to Build a blog application using laravel 5.3? at the previews tutorial, we have learn how to make simple blog system using laravel 5.3, please read here Laravel 5.3 Make Simple Blog.

In this lessons, we will build a blog application with new versions, so just following this tutorial for step by step.

Build a Blog System with Laravel 5.3

INTRODUCTIONS

What is this application?
This is a simple blogging application with the following features:
Build a Blog System with Laravel 5.3

  1. Anyone can login or register
  2. Users can be 'admin', 'author' or 'subscriber'.
  3. Authors can write/update/delete their own posts.
  4. Admin has full access on the website and can read/ write/ update/ delete any of the posts.
  5. Anyone can read these posts
  6. Users can comment on the posts (only after login)
  7. Use tinymce library to create posts
  8. Adding images in the post
  9. Costumize slug
  10. etc..

Here's Intruction Video tutorials


BUILD BLOG APPLICATION PROJECT

First step, we need to create new database using MySQL database, make sure you have database and named with "myblog2016".

Create Project

next step, create new laravel project, install laravel 5.3 using composer

composer create-project --prefer-dist laravel/laravel myblog

Next, open the project using text editor and create conection

Create Connection

setup connection to database, your database configuration is stored on .ENV file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myblog2016
DB_USERNAME=root
DB_PASSWORD=yourpassword

Create Table & Migrations

php artisan make:migration create_posts_table

php artisan make:migration create_comments_table

Posts migration file

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // posts table
        Schema::create('posts', function(Blueprint $table){
          $table->increments('id'); // table Id's
          $table -> integer('author_id') -> unsigned() -> default(0);
          $table->foreign('author_id')
                ->references('id')->on('users')
                ->onDelete('cascade');
          $table->string('title')->unique();
          $table->string('description'); // for meta description
          $table->text('body'); // our posts
          $table->string('slug')->unique();
          $table->string('images');
          $table->boolean('active');
          $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        // drop posts table
        Schema::drop('posts');
    }
}

Comments migration file

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCommentTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // comments table
        Schema::create('comments', function(Blueprint $table){
          $table->increments('id');
          $table -> integer('on_post') -> unsigned() -> default(0);
          $table->foreign('on_post')
                ->references('id')->on('posts')
                ->onDelete('cascade');
          $table -> integer('from_user') -> unsigned() -> default(0);
          $table->foreign('from_user')
                ->references('id')->on('users')
                ->onDelete('cascade');
          $table->text('body'); // our comments
          $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        // delete comments table
        Scheme::drop('comments');
    }
}

Create Authentication

php artisan make:auth

Edit user migrations file to add new role to database

            $table->string('password');
            // add new field in users table
            $table->enum('role',['admin','author','subscriber'])->default('author');
            $table->rememberToken();

Run migration

php artisan migrate

Video tutorial Setting up database



Create New Model

php artisan make:model Posts

php artisan make:model Comments

Posts Model

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;
class Posts extends Model {
    // restricts columns from modifying
    protected $guarded = [];
    // posts has many comments
    // returns all comments on that post
    public function comments(){
      return $this->hasMany('App\Comments','on_post');
    }
    // returns the instance of the user who is author of that post
    public function author(){
      return $this->belongsTo('App\User','author_id');
    }
}

Comments Model

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;
class Comments extends Model {
    // comments table in database
    protected $guarded = [];
    // user who has commented
    public function author(){
      return $this->belongsTo('App\User','from_user');
    }
    // returns post of any comment
    public function post(){
      return $this->belongsTo('App\Posts','on_post');
    }
}

Create New controller

php artisan make:controller PostsController --resource

php artisan make:controller CommnentsController --resource

PostsController.php

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Posts;
use App\User;
use Redirect;
class PostsController extends Controller {
    public function index() {
        //fetch 5 posts from database which are active and latest
        $posts = Posts::where('active',1)->orderBy('created_at')->paginate(2);
        // page Heading
        $title = 'Latest Post';
        // return to our view (home.blade.php)
        return view('home')->withPosts($posts)->withTitle($title);
    }
    // we need to show the single page of our posts
    public function show($slug) {
      $post = Posts::where('slug',$slug)->first();
      if (!$post) {
        return redirect('/')->withErrors('requested page not found');
      }
      $comments = $post->comments;
      return view('posts.show')->withPost($post)->withComments($comments);
    }
}

CommentsController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Posts;
use App\Comments;
use Redirect;
class CommentsController extends Controller {
    public function store(Request $request) {
        $input['from_user'] = $request->user()->id;
        $input['on_post'] = $request->input('on_post');
        $input['body'] = $request->input('body');
        $slug = $request->input('slug');
        Comments::create( $input );
        return redirect($slug)->with('message', 'Comment published');
    }
}

Add Routes

Auth::routes();
Route::get('/','PostsController@index');
Route::get('/home', 'PostsController@index');
Route::get('/{slug}', 'PostsController@show')->where('slug', '[A-Za-z0-9-_]+');
Route::group(['middleware' => ['auth']], function() {
  Route::post('comment/add','CommentsController@store');
});

Adding Bootstrap templates

Download bootstrap template for blog here https://startbootstrap.com/template-overviews/clean-blog/
After download bootstrap templates, just copy all file to laravel Project (Public Folder) see on videos tutorial.

Next, we need to create master templates blade.

Create Master Templates (for home Page)
Create new file in resources\views\layouts\app.blade.php

app.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">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Laravel 5.3 Blog System | www.hc-kr.com</title>

    <!-- Bootstrap Core CSS -->
    <link href="{{ asset('vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">

    <!-- Theme CSS -->
    <link href="{{ asset('css/clean-blog.min.css') }}" rel="stylesheet">

    <!-- Custom Fonts -->
    <link href="{{ asset('vendor/font-awesome/css/font-awesome.min.css') }}" rel="stylesheet" type="text/css">
    <link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>
<body>

    <!-- Navigation -->
    <nav class="navbar navbar-default navbar-custom navbar-fixed-top">
        <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header page-scroll">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    <span class="sr-only">Toggle navigation</span>
                    Menu <i class="fa fa-bars"></i>
                </button>
                <a class="navbar-brand" href="index.html">Start Bootstrap</a>
            </div>

            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="/">Home</a></li>
                    <li><a href="#">About</a></li>
                    <li><a href="#">Sample Post</a></li>
                    <li><a href="#">Contact</a></li>
                    @if (Auth::guest())
                      <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Members<span class="caret"></span></a>
                        <ul class="dropdown-menu" role="menu">
                          <li><a href="{{ url('/login') }}">Login</a></li>
                          <li><a href="{{ url('/register') }}">Register</a></li>
                        </ul>
                      </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="{{ url('/logout') }}">Logout</a></li>
                      </ul>
                    </li>
                    @endif
                </ul>
            </div>
            <!-- /.navbar-collapse -->
        </div>
        <!-- /.container -->
    </nav>

    <!-- Page Header -->
    <!-- Set your background image for this header on the line below. -->
    <header class="intro-header" style="background-image: url({{ asset('/img/'.$post->images) }})">
        <div class="container">
            <div class="row">
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                  @yield('header')
                </div>
            </div>
        </div>
    </header>

    <!-- Main Content -->
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-preview">
                  @yield('content')
                </div>
                @yield('pagination')
            </div>
        </div>
    </div>

    <hr>

    <!-- Footer -->
    <footer>
        <div class="container">
            <div class="row">
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    <ul class="list-inline text-center">
                        <li>
                            <a href="#">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                        <li>
                            <a href="#">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                        <li>
                            <a href="#">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                    </ul>
                    <p class="copyright text-muted">Copyright © Your Website 2016</p>
                </div>
            </div>
        </div>
    </footer>

    <!-- jQuery -->
    <script src="{{ asset('vendor/jquery/jquery.min.js') }}"></script>
    <!-- Bootstrap Core JavaScript -->
    <script src="{{ asset('vendor/bootstrap/js/bootstrap.min.js') }}"></script>
    <!-- Contact Form JavaScript -->
    <script src="{{ asset('js/jqBootstrapValidation.js') }}"></script>
    <script src="{{ asset('js/contact_me.js') }}"></script>
    <!-- Theme JavaScript -->
    <script src="{{ asset('js/clean-blog.min.js') }}"></script>
</body>

</html>

Update home.blade.php that stored on resources\views\home.blade.php

home.blade.php

@extends('layouts.app')
@section('header')
  <div class="site-heading">
    <h1>Sector Code</h1>
    <hr class="small">
    <span class="subheading">Simple Laravel 5.3 Blogs System, Share and subsribe our channel <br>
      More tutorial go to www.hc-kr.com
    </span>
  </div>
@endsection
@section('content')
  @if (!$posts->count())
    There is no post till now. Login and write a new post now!!!
  @else
  @foreach ($posts as $post)
      <h2 class="post-title">
        <a href="{{ url('/'.$post->slug) }}">{{ $post->title }}</a>
      </h2>
      <p class="post-subtitle">
        {!! str_limit($post->body, $limit= 120, $end = '....... <a href='.url("/".$post->slug).'>Read More</a>') !!}
      </p>
      <p class="post-meta">
        {{ $post->created_at->format('M d,Y \a\t h:i a') }} By <a href="{{ url('/user/'.$post->author_id)}}">{{ $post->author->name }}</a>
      </p>
  @endforeach
  @endif
@endsection
@section('pagination')
<div class="row">
  <hr>
  {!! $posts->links() !!}
</div>
@endsection

Next, create new master blade template for login/register page, that stored on resources\views\layouts\appadmin.blade.php

appadmin.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">
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>{{ config('app.name', 'Laravel') }}</title>
    <!-- Styles -->
    <link href="/css/app.css" rel="stylesheet">
    <!-- Scripts -->
    <script>
        window.Laravel = <?php echo json_encode([
            'csrfToken' => csrf_token(),
        ]); ?>
    </script>
</head>
<body>
    <div class="container">
      <div class="row">
        <div class="col-md-12">
          @yield('content')
        </div>
      </div>
    </div>
    <!-- Scripts -->
    <script src="/js/app.js"></script>
</body>
</html>

Next, update our login or register page, that stored on resources\views\auth\login.blade.php and resources\views\auth\register.blade.php

Just replace this code @extends('layouts.app')
to @extends('layouts.appadmin')

Video Tutorial showing posts, comments, bootstrap templates



Follow and subscribe for the next lessons....

Không có nhận xét nào:

Đăng nhận xét