Pada bagian ke empat ini, kita akan melakukan hal berikut :
- Mengganti data post yang statis dengan data yang berasal dari tabel posts.
- Pada home screen, post yang ditampilkan adalah post yang sudah di published.
Pertama-tama, kita tambahkan route di routes/web.php :
1 2 3 4 |
Route::get('/',[ 'uses' => 'BlogController@index', 'as' => 'blog', ]); |
Buka terminal dan buat BlogController.php :
1 |
php artisan make:controller BlogController |
BlogController.php akan muncul di dalam folder app/Http/Controllers.
Tambahkan public function index()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; class BlogController extends Controller { public function index(){ $posts = Post::all(); return view("blog.index", compact('posts')); } } |
Modifikasi resources/views/blog/index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<h1 class="my-4">Page Heading <small>Secondary Text</small> </h1> @foreach($posts as $post) <!-- Blog Post --> <div class="card mb-4"> <img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap"> <div class="card-body"> <h2 class="card-title">Post Title</h2> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis aliquid atque, nulla? Quos cum ex quis soluta, a laboriosam. Dicta expedita corporis animi vero voluptate voluptatibus possimus, veniam magni quis!</p> <a href="#" class="btn btn-primary">Read More →</a> </div> <div class="card-footer text-muted"> Posted on January 1, 2017 by <a href="#">Start Bootstrap</a> </div> </div> @endforeach <!-- Pagination --> |
Post akan muncul namun isinya sama. Kita akan melakukan beberapa perubahan :
Modifikasi model Post.php dan tambahkan accessor untuk mengambil attribut image_url getImageUrlAttribute :
1 2 3 4 5 6 7 8 9 10 11 |
public function getImageUrlAttribute($value){ $imageUrl = ""; if(!is_null($this->image)){ $imageUrl = $this->image; }else{ $imageUrl = ""; } return $imageUrl; } |
Buka Post.php model dan buat relationship dengan model User. Setiap post memiliki satu penulis. Kita mengambil informasi penulis dari tabel user.
1 2 3 |
public function author(){ return $this->belongsTo(User::class); } |
Buka User model dan buat relationship dengan Post model. Satu user dapat menulis lebih dari satu post. Dihubungkan dengan kolom author_id pada tabel post.
1 2 3 |
public function posts(){ return $this->hasMany(Post::class,'author_id'); } |
Modifikasi BlogController.php dengan menambahkan method with() supaya lebih efisien pemanggilan databasenya.
1 2 3 4 5 6 7 |
public function index(){ $posts = Post::with('author') ->get(); return view("blog.index", compact('posts')); } |
Ganti data statis menggunakan method diffForHumans yang disediakan oleh Carbon.
Buka Post.php model dan buat date accessor :
1 2 3 |
public function getDateAttribute($value){ return is_null($this->published_at) ? '' : $this->published_at->diffForHumans(); } |
Buat scopelatestFirst() di Post.php model untuk menampilkan post yang terakhir terlebih dahulu.
1 2 3 |
public function scopeLatestFirst($query){ return $query->orderBy('created_at', 'desc'); } |
Selanjutnya kita akan membuat pagination. Modifikasi BlogController.php :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class BlogController extends Controller { protected $limit = 5; public function index(){ $posts = Post::with('author') ->latestFirst() ->paginate($this->limit); return view("blog.index", compact('posts')); } } |
Modifikasi resources/views/blog/index.php
1 2 3 4 |
<!-- Pagination --> <ul class="pagination justify-content-center mb-4"> {{ $posts->links() }} </ul> |
Lalu, kita akan menampilkan post yang sudah dipublish saja. Kita perlu menambahkan satu kolom di tabel posts. Buka terminal dan ketik :
1 |
php artisan make:migration alter_posts_add_published_at_column --table=posts |
Modifikasi file migration :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AlterPostsAddPublishedAtColumn extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('posts', function (Blueprint $table) { $table->timestamp('published_at')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('posts', function (Blueprint $table) { $table->dropColumn('published_at'); }); } } |
Modifikasi poststableseeder.php dan tambahkan nilai published_at :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php use Illuminate\Database\Seeder; use Faker\Factory; use Carbon\Carbon; class PostsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { //reset posts table DB::table('posts')->truncate(); //generate 10 dummy posts $image = "http://placehold.it/750x300"; $posts = []; $faker = Factory::create(); $date = Carbon::create(2018, 7, 10, 11); for($i=1; $i<=10; $i++){ $date->addDays(1); $publishedDate = clone($date); $createdDate = clone($date); $posts[] = [ 'author_id' => rand(1,3), 'title' => $faker->sentence(rand(8,12)), 'excerpt' => $faker->text(rand(250,300)), 'body' => $faker->paragraphs(rand(10,15), true), 'slug' => $faker->slug(), 'image' => rand(0,1) == 1 ? $image : null, 'created_at' => $createdDate, 'updated_at' => $createdDate, 'published_at' => $i < 5 ? $publishedDate : ( rand(0,1) == 0 ? NULL : $publishedDate->addDays(4)), ]; } DB::table('posts')->insert($posts); } } |
Lakukan migrasi dan seed :
1 |
php artisan migrate:refresh --seed |
Buat scope published di dalam Post Model, dan modifikasi BlogController :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class BlogController extends Controller { protected $limit = 5; public function index(){ $posts = Post::with('author') ->latestFirst() ->published() ->paginate($this->limit); return view("blog.index", compact('posts')); } } |
1 2 3 |
public function scopePublished($query){ return $query->where("published_at", "<=", Carbon::now()); } |
Modifikasi layouts/main.blade.php untuk menambahkan route ke Home :
1 2 3 4 5 |
<li class="nav-item active"> <a class="nav-link" href="{{ route('blog') }}">Home <span class="sr-only">(current)</span> </a> </li> |
Berikut ini file – file yang kita rubah :
app\Post.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Carbon\Carbon; class Post extends Model { protected $dates = ['published_at']; public function getImageUrlAttribute($value){ $imageUrl = ""; if(!is_null($this->image)){ $imageUrl = $this->image; }else{ $imageUrl = ""; } return $imageUrl; } public function author(){ return $this->belongsTo(User::class); } public function getDateAttribute($value){ return is_null($this->published_at) ? '' : $this->published_at->diffForHumans(); } public function scopeLatestFirst($query){ return $query->orderBy('created_at', 'desc'); } public function scopePublished($query){ return $query->where("published_at", "<=", Carbon::now()); } } |
app\Http\Controllers\BlogController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; class BlogController extends Controller { protected $limit = 5; public function index(){ $posts = Post::with('author') ->latestFirst() ->published() ->paginate($this->limit); return view("blog.index", compact('posts')); } } |
resources\views\blog\index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
@extends('layouts.main') @section('content') <!-- Page Content --> <div class="container"> <div class="row"> <!-- Blog Entries Column --> <div class="col-md-8"> <h1 class="my-4"> </h1> @foreach($posts as $post) <!-- Blog Post --> <div class="card mb-4"> <img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap"> <div class="card-body"> <h2 class="card-title">{{ $post->title }}</h2> <p class="card-text">{{ $post->excerpt }}</p> <a href="#" class="btn btn-primary">Read More →</a> </div> <div class="card-footer text-muted"> Posted on {{ $post->date }} by <a href="#">{{ $post->author->name }}</a> </div> </div> @endforeach <!-- Pagination --> <ul class="pagination justify-content-center mb-4"> {{ $posts->links() }} </ul> </div> @include('layouts.sidebar') </div> <!-- /.row --> </div> <!-- /.container --> @endsection |
Hasilnya akan seperti ini :
Github Commit.