WordPress-Like Blog Laravel 5.7 and AdminLTE 3 (8) – Display Popular Posts
In this eighth part of creating WordPress-Like Blog using Laravel 5.6/5.7 and AdminLTE 3, we will :
- Create view_count column on the posts table
- Display popular posts widget on the sidebar
- Increment the displayed post by 1
Create view_count column on the posts table
The basic concept of the popular post, if a post is being opened, the counter will be incremented by 1. So we need to create a new column to store information how many has one post is displayed.
Create new migration :
1 |
php artisan make:migration alter_posts_add_viewcount --table=posts |
1 2 3 4 5 6 |
public function up() { Schema::table('posts', function (Blueprint $table) { $table->integer('view_count'); }); } |
Run the migration : php artisan migrate
Add the view_count seed to PostsTableSeeder.php
1 |
'view_count' => rand(1,10) * 10, |
Run the seeder : php artisan db:seed
Open Post model and add scopePopular() and image_thumb_url() method :
1 2 3 |
public function scopePopular($query){ return $query->orderBy('view_count', 'desc'); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public function getImageThumbUrlAttribute($value){ $imageUrl = ""; if(!is_null($this->image)){ $ext = substr(strrchr($this->image, '.'), 1); $thumbnail = str_replace(".{$ext}", "_thumb.{$ext}", $this->image); $imagePath = public_path() . "/img/" . $thumbnail; if(file_exists($imagePath)) $imageUrl = asset("img/" . $thumbnail); $imageUrl = $this->image; }else{ $imageUrl = ""; } return $imageUrl; } |
Display popular posts widget on the sidebar
Open layouts/sidebar.blade.php and add the following code :
1 2 3 4 5 6 7 8 9 10 |
<div class="card my-4"> <h5 class="card-header">Popular Posts</h5> <div> <ul class="list-group list-group-flush"> @foreach($popularPosts as $popularPost) <li class="list-group-item"><img src="{{ $post->image_thumb_url }}" width=35% alt=""><a href="{{ route('blog.show', $popularPost->slug)}}"> {{ substr($popularPost->title, 0, 20) }} ...<span class="badge badge-pill badge-secondary float-right">{{ $popularPost->view_count }} {{ str_plural('hit', $popularPost->view_count)}}</span></a></li> @endforeach </ul> </div> </div> |
Modify ComposerServiceProvider.php to add the posts, don’t forget to add use App\Post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public function boot() { view()->composer('layouts.sidebar', function($view){ $categories = Category::with(['posts' => function($query){ $query->published(); }])->orderBy('title','asc')->get(); return $view->with('categories',$categories); }); view()->composer('layouts.sidebar', function($view){ $popularPosts = Post::published()->popular()->take(3)->get(); return $view->with('popularPosts', $popularPosts); }); } |
Open the project url, now you will find the popular posts widget on the sidebar :
Increment the displayed post by 1
Modify BlogController the show() method :
1 2 3 4 5 |
public function show(Post $post){ $post->increment('view_count',1); return view("blog.show", compact('post')); } |
Ok, now our popular post has worked. However, before we end this part, let’s refactor the ComposerServiceProvider.php .
First, we create View folder in the app directory, and create Composers folder within that directory. We will put the view composer to this folder. Create a new file, NavigationComposer.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 |
<?php namespace App\Views\Composers; use Illuminate\View\View; use App\Category; use App\Post; class NavigationComposer{ public function compose(View $view){ $this->composeCategories($view); $this->composePopularPosts($view); } private function composeCategories(View $view){ $categories = Category::with(['posts' => function($query){ $query->published(); }])->orderBy('title', 'asc')->get(); $view->with('categories', $categories); } private function composePopularPosts(View $view){ $popularPosts = Post::published()->popular()->take(3)->get(); $view->with('popularPosts', $popularPosts); } } |
And modify the ComposerServiceProvider.php
1 2 3 4 |
public function boot() { view()->composer('layouts.sidebar', NavigationComposer::class); } |
Don’t forget to add namespace :
1 |
use App\Views\Composers\NavigationComposer; |
Ok, done!
Github Commit.