Download the PHP package tonysm/rich-text-laravel without Composer

On this page you can find all versions of the php package tonysm/rich-text-laravel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package rich-text-laravel

Total Downloads License

Integrates the Trix Editor with Laravel. Inspired by the Action Text gem from Rails.

Installation

You can install the package via composer:

Then, you may install it running:

Next, you may run the migration:

Ensure the styles Blade component were added to your layouts:

Alternatively, if you're using Breeze (or TailwindCSS), you may prefer the tweaked theme:

Finally, you may now use the published input Blade component on your forms like so:

That's it!

Overview

We extract attachments before saving the rich text field (which uses Trix) in the database and minimize the content for storage. Attachments are replaced with rich-text-attachment tags. Attachments from attachable models have a sgid attribute, which should globally identify them in your app.

When storing images directly (say, for a simple image uploading where you don't have a model for representing that attachment in your application), we'll fill the rich-text-attachment with all the attachment's properties needded to render that image again. Storing a minimized (canonical) version of the rich text content means we don't store the inner contents of the attachment tags, only the metadata needded to render it again when needed.

There are two ways of using the package:

  1. With the recommended database structure where all rich text content will be stored outside of the model that has rich text content (recommended); and
  2. Only using the AsRichTextContent trait to cast a rich text content field on any model, on any table you want.

Below, we cover each usage way. It's recommended that you at least read the Trix documentation at some point to get an overview of the client-side of it.

The RichText Model

The recommended way is to keep the rich text content outside of the model itself. This will keep the models lean when you're manipulating them, and you can (eagerly or lazily) load the rich text fields only where you need the rich text content.

Here's how you would have two rich text fields on a Post model, say you need one for the body of the content and another one for internal notes you may have:

This trait will create dynamic relationships on the Post model, one for each field. These relationships will be called: richText{FieldName} and you may define the fields using underscore, so if you had a internal_notes field, that would have a richTextInternalNotes relationship added on the model.

For a better DX, the trait will also add a custom cast for the body and notes fields on the Post model to forward setting/getting operations to the relationship, since these fields will NOT be stored in the posts table. This means that you can use the Post model like this:

And you can interact with the rich text fields just like you would with any regular field on the Post model:

Again, there's no body or notes fields on the Post model, these virtual fields will forward interactions to the relationship of that field. This means that when you interact with these fields, you're actually interacting with an instance of the RichText model. That model will have a body field that holds the rich text content. This field is then casted to an instance of the Content class. Calls to the RichText model will be forwarded to the body field on the RichText model, which is an instance of the Content class. This means that instead of:

Where the first "body" is the virtual field which will be an instance of the RichText model and the second "body" is the rich text content field on that model, which is an instance of the Content class, you can do:

Similarly to the Content class, the RichText model will implement the __toString magic method and render the HTML content (for the end user) by casting it to a string, which in blade can be done like this:

Note: since the HTML output is NOT escaped, make sure you sanitize it before rendering. See the sanitization section for more about this.

The HasRichText trait will also add an scope which you can use to eager load the rich text fields (remember, each field will have its own relationship), which you can use like so:

The database structure for this example would be something like this:

💡 If you use UUIDs, you may modify the migration that creates the rich_texts table to use uuidMorphs instead of morphs. However, that means all your model with Rich Text content must also use UUIDs.

We store a back-reference to the field name in the rich_texts table because a model may have multiple rich text fields, so that is used in the dynamic relationship the HasRichText creates for you. There's also a unique constraint on this table, which prevents having multiple entries for the same model/field pair.

Rendering the rich text content back to the Trix editor is a bit differently than rendering for the end users, so you may do that using the toTrixHtml method on the field, like so:

Next, go to the attachments section to read more about attachables.

Encrypted Rich Text Attributes

If you want to encrypt the HTML content at-rest, you may specify the encrypted option to true in the richTextAttributes property:

This uses Laravel's Encryption feature. By default, we'll encrypt using Laravel's Crypt::encryptString() and decrypt with Crypt::decryptString(). If you're coming from version 2 of the Rich Text Laravel package, which would default to Crypt::encrypt() and Crypt::decrypt(), you must migrate your data manually (see instructions in the 2.2.0 release). This is the recommended way to upgrade to 3.x.

With that being said, you may configure how the package handles encryption however you want to by calling the RichTextLaravel::encryptUsing() method on your AppServiceProvider::boot method. This method takes an encryption and decryption handler. The handler will receive the value, the model and key (field) that is being encrypted, like so:

Again, it's recommended that you migrate your existing encrypted data and use the default encryption handler (see instructions here).

Key Rotation

Laravel's Encryption component relies on the APP_KEY master key. If you need to rotate this key, you'll need to manually re-encrypt your encrypted Rich Text Attributes using the new key.

Additionally, the stored content attachments rely on the Globalid Laravel package. That package generates a derived key based on your APP_KEY. When rotating the APP_KEY, you'll also need to update all stored content attachments's sgid attributes.

The AsRichTextContent Trait

In case you don't want to use the recommended structure (either because you have strong opinions here or you want to rule your own database structure), you may skip the entire recommended database structure and use the AsRichTextContent custom cast on your rich text content field. For instance, if you're storing the body field on the posts table, you may do it like so:

Then the custom cast will parse the HTML content and minify it for storage. Essentially, it will convert this content submitted by Trix which has only an image attachment:

To this minified version:

And when it renders it again, it will re-render the remote image again inside the rich-text-attachment tag. You can render the content for viewing by simply echoing out the output, something like this:

Note: since the HTML output is NOT escaped, make sure you sanitize it before rendering. See the sanitization section for more about this.

When feeding the Trix editor again, you need to do it differently:

Rendering for the editor is a bit different, so it has to be like that.

Image Upload

Trix shows the attachment button, but it doesn't work out-of-the-box, we must implement that behavior in our applications.

A basic version of attachments uploading would look something like this:

The package contains a demo application with basic image uploading functionality implemented in the Workbench application. Here's some relevant links:

However, you're not limited to this basic attachment handling in Trix. A more advanced attachment behavior could create its own backend model, then set the sgid attribute on the attachment, which would let you have full control over the rendered HTML when the document renders outside the Trix editor.

Content Attachments

With Trix we can have content Attachments. In order to cover this, let's build a users mentions feature on top of Trix. There's a good Rails Conf talk building out this entire feature but with Rails. The workflow is pretty much the same in Laravel.

To turn any model into an Attachable, you must implement the AttachableContract. You may use the Attachable trait to provide some basic Attachable functionality (it implements most of the basic handling of attachables), except for the richTextRender(array $options): string method, which you must implement. This method is used to figure out how to render the content attachment both inside and outside of Trix.

The $options array passed to the richTextRender is there in case you're rendering multiple models inside a gallery, so you would get a in_gallery boolean field (optional) in that case, which is not the case for this user mentions example, so we can ignore it.

You may use Blade to render an HTML partial for the attachable. For a reference, the Workbench application ships with a User Mentions feature, which may be used as an example of content attachments. Here's some relevant links:

You can later retrieve all attachments from that rich text content. See The Content Object section for more.

The Content Object

You may want to retrieve all the attachables in that rich text content at a later point and do something fancy with it, say actually storing the User's mentions associated with the Post model, for example. Or you can fetch all the links inside that rich text content and do something with it.

Getting Attachments

You may retrieve all the attachments of a rich content field using the attachments() method both in the RichText model instance or the Content instance:

This will return a collection of all the attachments, anything that is an attachable, really, so images and users, for instance - if you want only attachments of a specific attachable you can use the filter method on the collection, like so:

Getting Links

To extract links from the rich text content you may call the links() method, like so:

Getting Attachment Galleries

Trix has a concept of galleries, you may want to retrieve all the galleries:

This should return a collection of all the image gallery DOMElements.

Getting Gallery Attachments

You may also want to get only the attachments inside of image galleries. You can achieve that like this:

Which should return a collection with all the attachments of the images inside galleries (all of them). You can then retrieve just the RemoteImage attachable instances like so:

Custom Content Attachments Without SGIDs

You may want to attach resources that don't need to be stored in the database. One example of this is perhaps storing the OpenGraph Embed of links in a chat message. You probably don't want to store each OpenGraph Embed as its own database record. For cases like this, where the integraty of the data isn't necessarily key, you may register a custom attachment resolver:

This resolver must either return an instance of an AttachableContract implementation or null if the node doesn't match your attachment. In this case of an OpengraphEmbed, this would look something like this:

You can see a full working implementation of this OpenGraph example in the Chat Workbench demo (or in this PR).

Plain Text Rendering

Trix content can be converted to anything. This essentially means HTML > something. The package ships with a HTML > Plain Text implementation, so you can convert any Trix content to plain text by calling the toPlainText() method on it:

As an example, this rich text content:

Will be converted to:

If you're attaching models, you can implement the richTextAsPlainText(?string $caption = null): string method on it, where you should return the plain text representation of that attachable. If the method is not implemented on the attachable and no caption is stored in the Trix attachment, that attachment won't be present in the Plain Text version of the content.

💡 The plain text output representation is not HTML-safe. You must escape the plain text version generated.

Sanitization

Since we're rendering user-generated HTML, you must sanitize it to avoid any security issues. Even though we control the input element, malicious users may tamper with HTML in the browser and swap it for something else that allows them to inject their own HTML.

We recommend using Symfony's HTML Sanitizer. The Workbench application in this repository ships with a sample implementation. Here's some relevant info:

Attention: I'm not an expert in HTML content sanitization, so take this with an extra grain of salt and, please, consult someone more with more security experience on this if you can.

SGID

When storing references of custom attachments, the package uses another package called GlobalID Laravel. We store a Signed Global ID, which means users cannot simply change the sgids at-rest. They would need to generate another valid signature using the APP_KEY, which is secret.

In case you want to rotate your key, you would need to loop-through all the rich text content, take all attachables with an sgid attribute, assign a new value to it with the new signature using the new secret, and store the content with that new value.

Livewire

If you want to use Livewire with Trix and Rich Text Laravel, the best way to integrate would be using Livewire's @entangle() feature. The Workbench app ships with an example app. Some interesting points:

Testing

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.


All versions of rich-text-laravel with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/contracts Version ^10.0|^11.0
spatie/laravel-package-tools Version ^1.9.2
tonysm/globalid-laravel Version ^1.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package tonysm/rich-text-laravel contains the following files

Loading the files please wait ....