In this tutorial, i’ll show you how to integrate tinymce editor in your laravel application. Tinymce is the most advanced and popular and free wysiwyg html editor.
All CMS for example WordPress has a module from which you can upload your media files like images and you can insert images inside editor. We are going to add file manager / image upload functionality to our editor.
Letβs do this.
Firstly, add this code to your blade file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <title>TinyMCE in Laravel</title> <meta name="description" content="TinyMCE in Laravel"> <meta name="author" content="NadjmanDev"> <!-- Fonts --> <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css"> <!-- Styles --> <style> html, body { background-color: #fff; color: #636b6f; font-family: 'Raleway', sans-serif; font-weight: 100; height: 100vh; margin: ; } .content { text-align: center; } .title { font-size: 84px; } .m-b-md { margin-bottom: 30px; } button { display: inline-block; font-weight: 500; cursor:pointer; border: 1px solid transparent; padding: 0.59rem 1rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.25rem; color: #ffffff; background-color: #4c84ff; border-color: #4c84ff; } </style> </head> <body> <div class="content"> <div class="title m-b-md"> Laravel </div> <form action="{{ route('tinymce.store') }}" method="POST"> @csrf <textarea class="form-control" name="content" id="description-textarea" rows="8"></textarea> <br/> <br/> <button type="submit">Save</button> </form> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.9.5/tinymce.min.js"></script> <script> var editor_config = { selector: '#description-textarea', directionality: document.dir, path_absolute: "/", menubar: 'edit insert view format table', plugins: [ "advlist autolink lists link image charmap preview hr anchor pagebreak", "searchreplace wordcount visualblocks visualchars code fullscreen", "insertdatetime media save table contextmenu directionality", "paste textcolor colorpicker textpattern" ], toolbar: "insertfile undo redo | formatselect styleselect | bold italic strikethrough forecolor backcolor permanentpen formatpainter | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media | fullscreen code", relative_urls: false, language: document.documentElement.lang, height: 300, } tinymce.init(editor_config); </script> </body> </html> |
Add this code to your web route in web.php.
1 2 3 4 5 6 7 | use Illuminate\Http\Request; Route::post('/', function (Request $request) { $content = $request->content; return view('show')->with(compact('content')); })->name('tinymce.store'); |
Next create view.blade.php and add this code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <title>TinyMCE in Laravel</title> <meta name="description" content="TinyMCE in Laravel"> <meta name="author" content="NadjmanDev"> </head> <body> {!! $content !!} </body> </html> |
Now when you run the code you will see this result below.
Good, tinymce is working. Let’s add post route to test our save button.
Now when you hit the save button you will see the tinymce content on the page. Great π.
Our next step is to add image upload fonctionality to our tinymce.
We need to add this package to our laravel project.
Execute this command to install the package
1 2 3 | composer require unisharp/laravel-filemanager:~1.8 |
For laravel 5.5 and up providers list and class alias step can be skipped.
Add it to your providers list, in config/app.php
1 2 3 4 | Unisharp\Laravelfilemanager\LaravelFilemanagerServiceProvider::class, Intervention\Image\ImageServiceProvider::class, |
And add class alias
1 2 3 | 'Image' => Intervention\Image\Facades\Image::class, |
Now publish the packageβs assests using
1 2 3 4 | php artisan vendor:publish --tag=lfm_config php artisan vendor:publish --tag=lfm_public |
After that we need to make small change for our example. Go to config/lfm.php file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //Before ... 'middlewares' => ['web', 'auth'], ... //After ... 'middlewares' => ['web'], ... |
We removed auth middleware because we are not not using authentication in this example.
We’re almost done. Last step is to add file browser callback to tinymce config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | var editor_config = { ... file_browser_callback : function (field_name, url, type, win) { var x = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[].clientWidth; var y = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[].clientHeight; var cmsURL = editor_config.path_absolute + 'laravel-filemanager?field_name=' + field_name; if (type == 'image') { cmsURL = cmsURL + "&type=Images"; } else { cmsURL = cmsURL + "&type=Files"; } tinyMCE.activeEditor.windowManager.open({ file: cmsURL, title: 'Filemanager', width: x * 0.8, height: y * 0.8, resizable: "yes", close_previous: "no" }); }, } |
This is full page blade updated
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <title>TinyMCE in Laravel</title> <meta name="description" content="TinyMCE in Laravel"> <meta name="author" content="NadjmanDev"> <!-- Fonts --> <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css"> <!-- Styles --> <style> html, body { background-color: #fff; color: #636b6f; font-family: 'Raleway', sans-serif; font-weight: 100; height: 100vh; margin: ; } .content { text-align: center; } .title { font-size: 84px; } .m-b-md { margin-bottom: 30px; } button { display: inline-block; font-weight: 500; cursor:pointer; border: 1px solid transparent; padding: 0.59rem 1rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.25rem; color: #ffffff; background-color: #4c84ff; border-color: #4c84ff; } </style> </head> <body> <div class="content"> <div class="title m-b-md"> Laravel </div> <form action="{{ route('tinymce.store') }}" method="POST"> @csrf <textarea class="form-control" name="content" id="description-textarea" rows="8"></textarea> <br/> <br/> <button type="submit">Save</button> </form> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.9.5/tinymce.min.js"></script> <script> var editor_config = { selector: '#description-textarea', directionality: document.dir, path_absolute: "/", menubar: 'edit insert view format table', plugins: [ "advlist autolink lists link image charmap preview hr anchor pagebreak", "searchreplace wordcount visualblocks visualchars code fullscreen", "insertdatetime media save table contextmenu directionality", "paste textcolor colorpicker textpattern" ], toolbar: "insertfile undo redo | formatselect styleselect | bold italic strikethrough forecolor backcolor permanentpen formatpainter | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media | fullscreen code", relative_urls: false, language: document.documentElement.lang, height: 300, file_browser_callback : function (field_name, url, type, win) { var x = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[].clientWidth; var y = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[].clientHeight; var cmsURL = editor_config.path_absolute + 'laravel-filemanager?field_name=' + field_name; if (type == 'image') { cmsURL = cmsURL + "&type=Images"; } else { cmsURL = cmsURL + "&type=Files"; } tinyMCE.activeEditor.windowManager.open({ file: cmsURL, title: 'Filemanager', width: x * 0.8, height: y * 0.8, resizable: "yes", close_previous: "no" }); }, } tinymce.init(editor_config); </script> </body> </html> |
And voila, you got yourself a working editor with a filemanager.
You have now fully working file manager / image uploader inside your tinymce.
Wait, we have to talk about security. Tinymce escape script tag automatically, but we need to add layer of security to avoid Cross-Site Scripting (XSS) Vulnerability.
HTMLPurifier is a well maintained tool that cleans up code and even fixes things like missing html tags or illegal html nesting.
Run this command to add HTMLPurifier
1 2 3 | composer require mews/purifier |
For laravel 5.5 and up providers list and class alias step can be skipped.
Add it to your providers list, in config/app.php
1 2 3 | Mews\Purifier\PurifierServiceProvider::class, |
And add class alias
1 2 3 | 'Purifier' => Mews\Purifier\Facades\Purifier::class, |
The default configuration for Purifier allows particular html elements and attributes to be used and some css styling as well.
If you want to make changes to the default configuration you can easily customize the configuration by publishing the configuration script using the command line:
1 2 3 | php artisan vendor:publish --provider="Mews\Purifier\PurifierServiceProvider" |
This creates a new file at config/purifier.php.
Let’s edit show.blade.php and use Purifier like this to clean the variable:
1 2 3 4 5 6 7 | ... {!! clean($content) !!} ... |
This will take our piece of data and run it through the HTMLPurifier and based on our configuration will remove any unapproved html elements or attributes and clean up the code so it is standards compliant.
Thanks for reading this article. Donβt forget to tell me where you used this editor and filemanager in your project.
Leave a Reply