1. Introduction
CKEditor is a powerful WYSIWYG editor that provides rich text editing capabilities. In this guide, we’ll integrate CKEditor in a Laravel application and enable image upload and delete functionality. This allows users to insert images directly into the editor and manage them seamlessly.
2. Problem Statement
By default, CKEditor does not provide a built-in way to upload and delete images. We need to configure custom routes and logic in Laravel to handle image storage and cleanup when an image is removed from the editor.
⚠️ Note: Ensure that your public directory has a writable uploads/ck
folder where CKEditor can store uploaded images. Also, set the ASSET_URL
in your .env
file for image deletion to work correctly:
ASSET_URL=http://localhost:8000/
3. Include CKEditor and jQuery via CDN
Add CKEditor and jQuery CDN links in your Blade template (e.g., resources/views/layout.blade.php
):
<textarea name="ckeditor_post" id="ckeditor_post" cols="30" rows="10"></textarea>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.ckeditor.com/4.20.1/standard/ckeditor.js"></script>
4. CKEditor Setup
Initialize CKEditor and configure the file upload and delete routes:
CKEDITOR.replace('ckeditor_post', {
allowedContent: true,
filebrowserUploadUrl: "{{ route('ckeditor-upload-image', ['_token' => csrf_token()]) }}",
filebrowserUploadMethod: 'form',
on: {
change: function(evt) {
var content = evt.editor.getData();
// Find all images in the editor
var imagesInEditor = $(content).find('img').map(function() {
return $(this).attr('src');
}).get();
// Store current images
var currentImages = evt.editor.currentImages || [];
evt.editor.currentImages = imagesInEditor;
// Detect removed images
var removedImages = currentImages.filter(function(image) {
return imagesInEditor.indexOf(image) === -1;
});
// Send AJAX request to remove images from the server
removedImages.forEach(function(image) {
$.ajax({
url: '{{ route('ckeditor-delete-image') }}',
method: 'POST',
data: {
src: image,
_token: '{{ csrf_token() }}'
},
success: function(response) {
console.log('Image deleted successfully');
},
error: function(error) {
console.error('Error deleting image:', error);
}
});
});
}
}
});
5. Routes
Add the following routes in web.php
to handle image uploads and deletions:
Route::post('ckeditor-upload-image', [PostController::class, 'uploadImage'])
->name('ckeditor-upload-image');
Route::post('ckeditor-delete-image', [PostController::class, 'deleteImage'])
->name('ckeditor-delete-image');
6. Controller Methods
Implement the uploadImage
and deleteImage
methods inside PostController
:
function uploadImage(Request $request)
{
$image = $request->upload;
$imagename = str_replace(' ', '', 'tutorial' . time() . $image->getClientOriginalName());
$image->move(public_path('uploads/ck/'), $imagename);
$url = asset('uploads/ck/' . $imagename);
$CKEditorFuncNum = $request->input('CKEditorFuncNum');
$response = "<script>window.parent.CKEDITOR.tools.callFunction(
$CKEditorFuncNum, '$url', 'uploaded')</script>";
@header('Content-Type:text/html;charset-utf-8');
echo $response;
}
function deleteImage(Request $request)
{
$filePath1 = str_replace(env('ASSET_URL'), '', $request->src);
$filePath = public_path($filePath1);
if (file_exists($filePath)) {
unlink($filePath);
}
echo 'done';
}
7. Conclusion
This setup ensures a clean and manageable way to handle images in CKEditor. The integration handles both uploading and automatic deletion of unused files, keeping your server storage tidy.