How to integrate tinymce editor in laravel 11(with livewire)
First, we need to add third party script to our blade file. We can use @asset directive for injecting third party script.
@assets<script src="{{ asset('build/public/js/tinymce/tinymce/tinymce.min.js') }}" referrerpolicy="origin"></script><script> tinymce.init({ selector: '#details', // Replace this CSS selector to match the placeholder element for TinyMCE plugins: 'preview importcss searchreplace autolink autosave directionality anchor insertdatetime advlist lists quickbars emoticons', toolbar: "blocks fontfamily fontsize | bold italic underline strikethrough | align numlist bullist | forecolor backcolor emoticons", promotion: false, menubar: '', height: 500, branding: false, statusbar: false, setup: function(editor) { editor.on('init change', function() { editor.save(); }); editor.on('change', function(e) { @this.set('details', editor.getContent()); }); }, });</script>@endassets
After adding this, tinymce edit shows up. Because I am using Livewire for the front part, I had to add wire:ignore to the parent element of #details. Also whenever the content of the editor changes, it will update the $details property with updated contents.
I wanted to save this content to the database(MySQL). To handle every images in the content, I needed to use dom parser.
public function save(){ // save this product to retrieve id of the product. $newProrduct = new Product(); $newProrduct->user_id = auth()->user()->id; ... // set all the property for the new product. $newProrduct->save(); // partse the content from the Tinymce editor $dom = new \DomDocument(); $dom->loadHtml($this->details, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // get all images $imageFile = $dom->getElementsByTagName('img'); foreach ($imageFile as $item => $image) { $data = $image->getAttribute('src'); list($type, $data) = explode(';', $data); list(, $data) = explode(',', $data); $imageData = base64_decode($data); $image_name = time() . $item . '.png'; // create a folder name with its id and save all the images in it. // I am using r2 storage. Storage::disk('r2')->put("products/{$newProrduct->id}/" . $image_name, $imageData); $image->removeAttribute('src'); $image->setAttribute('src', env('CLOUDFLARE_R2_URL') . "products/{$newProrduct->id}/" . $image_name); } // save adjusted contents to the database $newProrduct->details = $dom->saveHTML(); $newProrduct->save(); return redirect()->intended(route('products'));}
The logic is pretty simple and straight forward. It might be good idea to create a method for handling images from the contents from the tinymce editor.