To manage content on the website, you always require a rich text editor aka WYSIWYG editor. The rich text content includes HTML tags that can be added only through the WYSIWYG editor. The textarea tag can’t handle content wrapped inside HTML.
There are numerous rich text editors(TinyMCE, CKEditor) available on the Internet. Trix Editor is one of them. It is developed by Basecamp. The Trix editor is being used in Basecamp for managing content. This is enough to say about the reliability of this WYSIWYG editor.
The purpose of this article is to show you how to install and use the Trix editor in Laravel. I’ll also explain how to upload images in the Trix editor. Following this tutorial, you’ll be able to handle rich text content in your Laravel application.
Installation of Trix Editor
For getting started with Trix, you first need to include their JS and CSS files. Get these files from the below URLs.
To include the above assets, create a js
and css
folder inside the public
directory of your Laravel project. Place the copied files in their respective directories.
Uploading images on the server using Trix requires writing some code in JavaScript. Create the attachments.js
file and keep it under the public/js
folder. We will add JavaScript code to this file in the later part of the tutorial.
Next, let’s define the routes in Laravel. We have to achieve 3 tasks.
- Display Trix Editor
- Upload images in Trix Editor
- Handle content submitted via Trix Editor
The following routes will handle these tasks.
Route::get('/trix', 'TrixController@index');
Route::post('/upload', 'TrixController@upload');
Route::post('/store', 'TrixController@store');
Create a TrixController
using the Artisan command:
php artisan make:controller TrixController
The boilerplate of TrixController
would be as follows.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TrixController extends Controller
{
public function index()
{
return view('trix');
}
public function store(Request $request)
{
}
public function upload(Request $request)
{
}
}
Display Trix Editor
Now, create a trix.blade
file and add the following HTML to it. It will display the Trix editor.
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="{{ asset('/css/trix.css') }}">
</head>
<body>
<form method="post" action={{ url('store') }}>
@csrf
<p>
<input id="x" type="hidden" name="content" value="" />
<trix-editor input="x" class="trix-content"></trix-editor>
</p>
<input type="submit" name="submit" value="Submit" />
</form>
<script src="{{ asset('js/trix.umd.min.js') }}"></script>
<script src="{{ asset('js/attachments.js') }}"></script>
</body>
</html>
After this, your Trix editor will be shown something like the screenshot below.
We placed the Trix editor in HTML using the trix-editor
tag. We also added the hidden field that will be used to get or show content in the Trix editor. This hidden field has the id
“x” which is the same as the editor’s input
attribute. When you type anything inside Trix, the content is set to the value of this hidden field. On the server side, you can get the content of the Trix editor as follows.
public function store(Request $request)
{
echo $request->input('content');
}
If you want to populate content in Trix, set the value to the hidden field as
<input id="x" type="hidden" name="content" value="<h1>This is content</h1>" />
Upload Image in Trix Editor
To add images in the Trix editor, you need to upload them on the server. Trix editor provides an event trix-attachment-add
through which you can send the image to the server via Ajax. We have already added the upload
route for it. Let’s define a method mapped with this route.
public function upload(Request $request)
{
if($request->hasFile('file')) {
//get filename with extension
$filenamewithextension = $request->file('file')->getClientOriginalName();
//get filename without extension
$filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
//get file extension
$extension = $request->file('file')->getClientOriginalExtension();
//filename to store
$filenametostore = $filename.'_'.time().'.'.$extension;
//Upload File
$request->file('file')->storeAs('public/uploads', $filenametostore);
// you can save image path below in database
$path = asset('storage/uploads/'.$filenametostore);
echo $path;
exit;
}
}
Here, I am storing images under the public/uploads
directory. So create a symbolic link to the storage folder using the command:
php artisan storage:link
The attachments.js
file will be used to give an Ajax call on the trix-attachment-add
event. The following code will handle the Ajax request and response.
attachments.js
(function() {
var HOST = "http://localhost:8000/upload"; //pass the route
addEventListener("trix-attachment-add", function(event) {
if (event.attachment.file) {
uploadFileAttachment(event.attachment)
}
})
function uploadFileAttachment(attachment) {
uploadFile(attachment.file, setProgress, setAttributes)
function setProgress(progress) {
attachment.setUploadProgress(progress)
}
function setAttributes(attributes) {
attachment.setAttributes(attributes)
}
}
function uploadFile(file, progressCallback, successCallback) {
var formData = createFormData(file);
var xhr = new XMLHttpRequest();
xhr.open("POST", HOST, true);
xhr.setRequestHeader( 'X-CSRF-TOKEN', getMeta( 'csrf-token' ) );
xhr.upload.addEventListener("progress", function(event) {
var progress = event.loaded / event.total * 100
progressCallback(progress)
})
xhr.addEventListener("load", function(event) {
var attributes = {
url: xhr.responseText,
href: xhr.responseText + "?content-disposition=attachment"
}
successCallback(attributes)
})
xhr.send(formData)
}
function createFormData(file) {
var data = new FormData()
data.append("Content-Type", file.type)
data.append("file", file)
return data
}
function getMeta(metaName) {
const metas = document.getElementsByTagName('meta');
for (let i = 0; i < metas.length; i++) {
if (metas[i].getAttribute('name') === metaName) {
return metas[i].getAttribute('content');
}
}
return '';
}
})();
I have assigned the upload
route to the HOST
variable. Laravel requires a CSRF token for each request. I am fetching this token from the meta tag added in the blade file. When you add the image in Trix, it triggers the Ajax request, uploads the image on the server, and returns the path of the uploaded image. This image then appends in the Trix editor. You can add styling to these images using the trix-content
class of the trix-editor
tag.
.trix-content img {
width: 300px;
height: 300px;
}
I hope you understand how to install and use the Trix editor in Laravel. Check out the documentation to read more about the Trix editor.
Related Articles
- How to Install and Use CKEditor in Laravel
- How to Install and Use TinyMCE Editor in Laravel
- Resize Image in Laravel Using Intervention Image Library
If you liked this article, then please subscribe to our YouTube Channel for video tutorials.
Hallo, this has been an excelent tutorial.
I’d like to know te proper way to remove the file listening to the ” trix-attachment-remove ” event. I’m using Laravel 8.
Also, I’d like to store the path with te foreignKey related, in order to be able to authorize the access to the corresponding user.
As you might imagine, I feel confortable with Laravel and PHP, but not so much bith javascript.
Thanks anyway. Best regards. Hern’an.