I believe you have read many articles over the internet, you might see some articles in blog post has display estimated minutes how long you to finished reading the post. Today I will show quick example to implement estimated reading time in Laravel 9.
Placing an estimated reading time can help reader consider to read our article in mean time. By the average human can read about 200 words in minutes so this is a value that we are going to calculate how long does it take to finished reading the post.
Also Read: Laravel 9 - Send Email with Template Example
You have to installed Laravel framework. Read this to know how to install Laravel project with database.
We will implement algorithm in Model class so that we can use the method as field (Laravel Accessor) . To generate migration file at the same time generate the model, you may use the --migration
or -m
option
php artisan make:model Post -m
Open file app -> models -> post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Str;
class Post extends Model
{
use HasFactory;
private function getReadingTime($content, $wpm = 200)
{
$wordCount = str_word_count(strip_tags($content));
$minutes = (int) floor($wordCount / $wpm);
$seconds = (int) floor($wordCount % $wpm / ($wpm / 60));
if ($minutes === 0)
{
return $seconds." ".Str::of('second')->plural($seconds);
}
else
{
return $minutes." ".Str::of('minute')->plural($minutes);
}
}
// to use attribute reading_time in blade file
protected function readingTime(): Attribute
{
return Attribute::make(function ($value, $attributes)
{
// use field text to check reading time
$time = $this->getReadingTime($attributes['text']);
return $time;
});
}
}
If you use lower version than Laravel 9, use Accessor as below or read. The format method contain prefix get and suffix Attribute
public function getReadingTimeAttribute($value)
{
return $this->getReadingTime($this->text);
}
Open file database -> migrations -> 2022_06_29_015322_create_posts_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug');
$table->text('text');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
Run migration by below command to create table in database
php artisan migrate
Open file routes -> web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', [PostController::class, 'index']);
We will create a method to show record post on webpage. Following command to create controller and update code below.
php artisan make:controller PostController
Open file app -> Http -> Controllers -> PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class PostController extends Controller
{
// Render index page
public function index()
{
return view("index",["posts"=>Post::all()]);
}
}
We will get new field (attribute) which we have implement in Model Class to show estimate reading time in li element. You might see there is no field reading_time defined but we have implement in Model class, take look at Model Class what we have implemented.
Create file resources -> views -> index.blade.php
<!DOCTYPE html>
<html>
<body>
<h1>Estimate Reading Time - cambotutorial.com</h1>
@foreach($posts as $item)
<li> {{$item->title}} - {{ $item->reading_time }} </li>
@endforeach
</body>
</html>
Finally, run Laravel server by following command
php artisan serve
Open URL http://localhost:8000/ you will see list of record with estimated reading time base on the body text pass to check.
Hope this tutorial help you to finished the project. Have a nice day !
You might Also Like:
Founder of CamboTutorial.com, I am happy to share my knowledge related to programming that can help other people. I love write tutorial related to PHP, Laravel, Python, Java, Android Developement, all published post are make simple and easy to understand for beginner. Follow him