CKEditor is a smart rich text editor that comes up with advanced options to manage your content. Generally, if you want your content to be stored in the actual HTML format then a WYSIWYG editor is required. The rich text editor solves your problem in case you are managing a kind of CMS. The normal HTML Textarea cannot fulfill your requirement for having HTML formatting. Also, if you want to include images with the content then it is not possible without a rich text editor. Today we will talk about CKEditor 4 implementation in Laravel 8. Also, we will see the file upload in CKEditor 4. We have already seen the CKEditor 5 integration in Laravel 8.
Prerequisites
Today, we will integrate the CK Editor 4 in the Laravel 8 application. But, we will be creating a new application in Laravel 8. In order to create the new project, you will have to meet with following requirements.
- PHP >= 7.3
- MySQL (version > 5)
- Apache/Nginx Server
- VS Code Editor
- Composer
Create a New Project in Laravel 8 For Integrating CKEditor 4
At the very first, we will set up the Laravel 8 project. Secondly, we will integrate the CKEditor 4. For creating a new project, I will be using the composer. Therefore, open the terminal and enter the below command.
composer create-project --prefer-dist laravel/laravel ckeditor
The installation can take a couple of minutes. So, once it is completed, we will move to the next step.
We will require a database connection. Hence, let’s do that.
Configure a Database in Laravel 8
Firstly, create a database then integrate it with your application. For the database, I will use MySQL. I have created the below database.
CREATE DATABASE laravel_ckeditor
After creating the database, let’s come to the Laravel 8 application. Navigate to the .env file. Under the DB section, configure it with the below credentials.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_ckeditor
DB_USERNAME=root
DB_PASSWORD=root
Now, our application is ready. But, we will require to have the controller, view, and a route to integrate the CKEditor 4. Hence, let’s create it one by one.
Create a Model, Migration, and Controller
Switch back to the terminal and hit the below command. Here, this command will generate a model, a migration, and a controller for Post.
php artisan make:model Post -mc
Here, we have the files ready for a model, migration, and controller.
At the very first step, you have to set up the migration file for the post table schema.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->longText('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
Secondly, you need to add the fillable data in the Post model. So, let’s do that.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description'
];
}
Migrate Table Schema in Laravel 8
In the next step, you have to run the migrate command to dump the schema in the database. So, switch back to the terminal and hit the below command.
php artisan migrate
It will dump available schemas in the database.
Now, you have the table(s) ready. So, in the next step, we will download CKEditor 4.
Download CKEditor 4
For downloading the CKEditor 4 CDN, just go to the official website of CDN CKeditor and get the CDN from here. You may download the source file and keep it in your local project folder as per your need. But, here, I will be using the CDN for just a demonstration purpose.
<script src="https://cdn.ckeditor.com/4.17.1/standard/ckeditor.js"></script>
Now, in the next step, you will need a View in which you will implement this CDN.
Create a View in Laravel 8 For Integrating CKEditor 4
For the better implementation of CKEditor 4, I will create a basic blog post example. Basically, we will create the post and then will display the created posts in the tabular form. Therefore, it will require the below views-
- index.blade.php
- create.blade.php
After creating the blades files, let’s add the below code snippet.
<!doctype html>
<html lang="en">
<head>
<title> Post Listing </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<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 font-weight-bold"> CK Editor 4 in Laravel 8 </h3>
</div>
<div class="col-xl-4 text-right">
<a href="{{ route('posts.create')}} " class="btn btn-primary"> Add Post </a>
</div>
</div>
<div class="table-responsive mt-4">
<table class="table table-striped">
<thead>
<tr>
<th> Id </th>
<th style="width:30%;"> Title </th>
<th> Decription </th>
</tr>
</thead>
<tbody>
@if(count($posts) > 0)
@foreach($posts as $post)
<tr>
<td> {{ $post->id }} </td>
<td> {{ $post->title }} </td>
<td> {!! html_entity_decode($post->description) !!} </td>
</tr>
@endforeach
@else
<tr>
<td colspan="3"> <p class="text-danger text-center"> No post found! </p> </td>
</tr>
@endif
</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>
Similarly, add the below snippet in the second view.
<!doctype html>
<html lang="en">
<head>
<title> Create Post - CKEditor 4 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">
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<meta name="csrf-token" content="{{ csrf_token() }}" />
{{-- CKEditor 4 CDN --}}
<script src="https://cdn.ckeditor.com/4.17.1/standard/ckeditor.js"></script>
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-xl-12 text-right">
<a href="{{ route('posts') }}" class="btn btn-danger"> Back </a>
</div>
</div>
<form action="{{ route('posts.store') }}" method="POST">
@csrf
<div class="row">
<div class="col-xl-8 col-lg-8 col-sm-12 col-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 font-weight-bold"> CK Editor 4 in Laravel 8 </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="description" placeholder="Enter the Description"
name="description"></textarea>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success"> Save </button>
</div>
</div>
</div>
</div>
</form>
</div>
<script>
CKEDITOR.replace('description', {
filebrowserUploadUrl: "{{ route('posts.upload', ['_token' => csrf_token()]) }}",
filebrowserUploadMethod: 'form'
})
</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>
Add the Functionality in Controller
Navigate to the PostController and add the below snippet. In the below snippet, I have added the functionality of ready content from the form. Also, there is the file upload functionality which will be coming from the CKEditor 4.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Post Display
* @param NA
* @return view
*/
public function index()
{
$posts = Post::paginate(10);
return view('index', compact('posts'));
}
/**
* Create Post
* @param NA
* @return view
*/
public function create()
{
return view('create-post');
}
/**
* Store Post
* @param request
* @return response
*/
public function store(Request $request)
{
$postRequest = array(
"title" => $request->title,
"description" => $request->description
);
$post = Post::create($postRequest);
if ($post) {
return back()->with("success", "Success! Post created");
} else {
return back()->with("failed", "Failed! Post not created");
}
}
/**
* Upload image
* @param request
* @param response
*/
public function uploadImage(Request $request)
{
if($request->hasFile('upload')) {
//get filename with extension
$filenamewithextension = $request->file('upload')->getClientOriginalName();
//get filename without extension
$filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
//get file extension
$extension = $request->file('upload')->getClientOriginalExtension();
//filename to store
$filenametostore = $filename.'_'.time().'.'.$extension;
//Upload File
$request->file('upload')->move('public/uploads', $filenametostore);
$CKEditorFuncNum = $request->input('CKEditorFuncNum');
$url = asset('public/uploads/'.$filenametostore);
$message = 'File uploaded successfully';
$result = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$message')</script>";
// Render HTML output
@header('Content-type: text/html; charset=utf-8');
echo $result;
}
}
}
In the next step, you will need the routes.
Add Routes For CKEditor with Image Upload
For adding routes, navigate to the web.php file and add the below routes.
<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::get('posts', [PostController::class, 'index'])->name('posts');
Route::get('posts/create', [PostController::class, 'create'])->name('posts.create');
Route::post('posts/store', [PostController::class, 'store'])->name('posts.store');
Route::post('uploads', [PostController::class, 'uploadImage'])->name('posts.upload');
The event of file upload from CKEditor 4 is already added in the create-post.blade.php.
Result of CKEditor 4
Run your application in the browser to see the result. When you are on the index route then the post listing view will be showing. Initially, we don’t have the posts. But, there is an option to create a new post.
When you will click on the Add Post, it will redirect you to a new URL. Now, you will have the below result. Here, we implemented the CKEditor 4 in the textarea.
Now, try to add a post here. After adding a title and body of the post. From the CKEditor toolbar when you will click on the image option, it will open the Image Properties dialog window as shown below.
There are different options available here. For uploading any file from your local computer, you will need to click on the Upload section.
Choose the file that you want to upload and click on Send it to the Server button. On successful upload, the file will be stored in the specified directory in the same project. Also, you will get the success response in the alert as shown below.
After uploading the file, simply click on the OK button. It will generate a preview of the uploaded image.
In the preview, you will have to confirm by clicking on the OK button. This will include the uploaded file in the content as shown below.
Now save the post. If the post is created, it will return the success response as shown below.
Conclusion
We integrated CKEditor 4 in the Laravel 8 application. Here, we stored the content in the MySQL database. Also, we displayed the post exactly the same as we stored. Using CKEditor 4, we uploaded images with content as well. So, I hope this will be a very helpful guide for you all while integrating CKEditor in Laravel 8. If you have any doubt related to this post then don’t forget to post it through the comment.
Leave a Reply