In this tutorial, we are going to create a new Laravel application for creating blogs or posts. While creating a blog we’ll use CKEditor to take input or HTML input and store it in our database.
Before starting, let’s understand why CKEditor is useful compared to HTML elements like text-area or inputs. The CKEditor is a rich text editor which means it has basic formatting abilities like font size, color, family, and more. But with the latest release, you can almost use it like Microsoft Word. You can show tables, headers, images, links, and many more things with the help of CKEditor.
As you know HTML text area or input can allow us to submit some data as text but can not take inputs like HTML elements titles or tables. Plugins like CKEditor provide a way to create HTML-based format converting user input into text.
For a better understanding of implementation we have divided the program into a few steps :
- Create a new Laravel Application
- Database Configuration
- Creating Model and Migrations
- Controller Logic
- Adding Views
- Define Routes
- Testing Application
Create a new Laravel Application
Let’s begin this tutorial by creating a new Laravel application. Navigate to your localhost directory based on XAMPP or WAMPP then you can create a fresh Laravel application with one of the below commands:
composer create-project --prefer-dist laravel/laravel Blog
//If you already installed laravel globel installer
laravel new Blog
It will take some time to create a new application and downloading/set new files.
Database Configuration
Let’s configure a database for our application. If you don’t have a database then create a new one. After making the database open the .env file from root directory of your project. The .env file defines many common environment variables
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=YOUR_DATABASE_NAME
DB_USERNAME=USERNAME
DB_PASSWORD=PASSWORD
Creating Model and Migrations
In this example, we will integrate CKEditor store its input into our database, and render it back whenever we require. For database operation in Laravel, we need to create a model which handles database operation for a particular table.
Here, we will simply create a post model and define two columns to store the title and content. In an actual project, you can define a number of columns in your model as per your requirements.
To create a model and migration enter the below command to the terminal :
php artisan make:model Post -m
This will create a Contact model and a migration file. In the terminal, we get an output similar to:
Model created successfully.
Created Migration: 2019_01_27_193840_create_posts_table
After completion of the command’s execution. let’s define the table schema for post table. Open the database/migrations/xxxxxx_create_posts_table migration file and update it accordingly:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}
Here, We added the title and body fields in the posts table structure.
Let’s make some changes to our model so we can use mass assignment for this table. Open the app/models/Post.php file and update it accordingly:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'body',
];
}
Now, we have defined the database structure and made the necessary changes to our model. It’s time to create an actual table in our database. Open the terminal and enter the below command:
php artisan migrate
It will generate a table in your database specified in .env file. You can verify that in phpMyAdmin.
Controller Logic
Controllers are meant to group associated request handling logic within a single class. For operations related to Post, we have to create a controller. You can use any other controller or existing controller for this task but we suggest creating a separate controller as per your logic. It will help you to maintain minimum response time and code understanding.
In your terminal, run the following command to create a controller:
php artisan make:controller PostController
This command will generate a controller at app/Http/Controllers/PostController.php. Here, we will define methods for post-operations. Let’s modify it as per our logic:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index() {
$posts = Post::orderBy("id", "desc")->paginate(10);
return view("welcome", compact("posts"));
}
public function create() {
return view("create_post");
}
public function store(Request $request) {
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
Post::create([
"title" => $request->title,
"body" => $request->body
]);
return back()->with("success", "Post has been created");
}
}
Here, we have used the Post Model and defined three different methods. The index method will get all post data and pass it to show a listing of posts/blogs. While the create method will just return create a view which contains Form with CKEditor. At last, the store method will handle the save process based on user input.
Adding Views
The view performs all front-end functionality of our application like displaying data, getting user input or getting requests. In this example, we need to create 1 view and we will modify the default welcome view. The first view will be displayed on the home page and show stored post data while the second view will be used to get post-related user input.
We’ll use the default welcome view to display a list of posts. Open welcome view and modify as below:
<!doctype html>
<html lang="en">
<head>
<title> Laravel CKEditor Example </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
table td p {
word-break: break-all;
}
</style>
</head>
<body>
<div class="container mt-4">
<div class="row">
<div class="col-xl-8">
<h3 class="text-right"> Laravel CKEditor Example</h3>
</div>
<div class="col-xl-4 text-right">
<a href="{{url('create')}}" class="btn btn-primary"> Add Post </a>
</div>
</div>
<div class="table-responsive mt-4">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th> Id </th>
<th style="width:30%;"> Title </th>
<th> Content </th>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td> {{ $post->id }} </td>
<td> {{ $post->title }} </td>
<td> {!! html_entity_decode($post->body) !!} </td>
</tr>
@endforeach
</tbody>
</table>
</div>
{{ $posts->links() }}
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Here, we just added a simple link to navigate to the post creation page and a table to display posts. At bottom of the table, we have included pagination links too so it will display 10 posts at a time.
Let’s create another view for a form that will handle post inputs. Create a new file with the name create_post.blade.php and add below code in it.
<!doctype html>
<html lang="en">
<head>
<title> Laravel 8 Install CKEditor Example </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
{{-- CKEditor CDN --}}
<script src="https://cdn.ckeditor.com/ckeditor5/23.0.0/classic/ckeditor.js"></script>
</head>
<body>
<div class="container mt-5">
<form action="{{url('store')}}" method="POST">
@csrf
<div class="row">
<div class="col-md-12 m-auto">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ Session::get('success') }}
</div>
@elseif(Session::has('failed'))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ Session::get('failed') }}
</div>
@endif
<div class="card shadow">
<div class="card-header">
<h4 class="card-title"> Create Post </h4>
</div>
<div class="card-body">
<div class="form-group">
<label> Title </label>
<input type="text" class="form-control" name="title" placeholder="Enter the Title">
</div>
<div class="form-group">
<label> Body </label>
<textarea class="form-control" id="content" placeholder="Enter the Description" rows="5" name="body"></textarea>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success"> Save </button>
<a href="{{ url('/') }}" class="btn btn-danger"> Back </a>
</div>
</div>
</div>
</div>
</form>
</div>
<script>
ClassicEditor.create( document.querySelector( '#content' ) )
.catch( error => {
console.error( error );
} );
</script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Here, we have created a simple form that takes two inputs. The first one is a title and the second is the body part of the post. We have also added CDN for CKEditor at the header.
In the script part, we have initialized the CKEditor instance on text-area input by passing the ID of input. It will convert a normal text area into a Rich text editor using CKEditor plugin functionality.
Define Routes
In this step, we will define routes for posts. This route will handle user requests and deliver it to a specific controller and its method. In Laravel, All web routes must be added to a particular file routes/web.php. You can create a custom route file and bind it to your application.
Open the web routes file and update it accordingly:
<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::get('/', [PostController::class, "index"]);
Route::get("create", [PostController::class, "create"]);
Route::post('store', [PostController::class, "store"]);
Testing Application
For Running or Testing the CRUD application enter the below command :
php artisan serve
It will produce output like below :
Starting Laravel development server: http://127.0.0.1:8000
PHP 7.4.6 Development Server (http://127.0.0.1:8000) started
Open your browser go to the below URL and test your application.
http://127.0.0.1:8000
In case, you are facing an issue while running the application verify the CKEditor link or check the console for error logs.
Conclusion
In this article, we have created functionality to create post using CKEditor and display them using a table. There are many useful methods and functionalities of CKEditor which can be useful as Image upload, enabling or disabling some formatting functionality, showing HTML code based on user input, and many more.