Laravel Estimate Article Reading in Minutes

Sovary June 29, 2022 1.33K
4 minutes read

estimate-reading-time-laravel 9

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.

Estimated Reading Time Article

Also Read: Laravel 9 - Send Email with Template Example

Step 1 - Install Laravel 9 & Setup Database

You have to installed Laravel framework. Read this to know how to install Laravel project with database.

Step 2 - Create Model & Migration

Create Model

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);      
}

Update Migration

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

Step 3 - Adding Route

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']);

Step 4 - Create Controller

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()]);
  }
}

Step 5 - Create Blade

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>

Step 6 - Run Laravel Server

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.

demo estimate reading time article laravel

Hope this tutorial help you to finished the project. Have a nice day !

You might Also Like:

Laravel  PHP  Laravel 9 
Author

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