rich-text-laravel Documentation

repository·main·Indexed 19 days ago

https://github.com/tonysm/rich-text-laravel

A Laravel package for integrating rich text editors like Trix and Lexxy, inspired by the Rails Action Text gem. It provides tools for handling rich text content in models and forms, supporting separate storage tables, encrypted attributes, and custom attachables. Features include Blade components for editors, conversion to plain text or Markdown, and an editor-agnostic interface for implementing custom editors.

Tokens
9.2K
Snippets
41
Records
44
Agent score
66%

What's inside rich-text-laravel

  1. How SGIDs work for attachables

    main
    The Attachable trait automatically generates a Signed Global ID (SGID) for the model via richTextSgid(). This SGID is stored in the <rich-text-attachment sgid="..."> tag in the canonical HTML. When content is rendered, the AttachableFactory resolves the SGID back to the original model. SGIDs are signed using your APP_KEY and never expire for rich text attachments.
  2. Include rich-text styles in your layout

    main

    To ensure the rich text editors render correctly, add the styles Blade component to your application's layout. If you are using DaisyUI, you can pass the theme="daisyui" option to use a tweaked theme.

    {{-- Standard styles --}}
    <x-rich-text::styles />
    
    {{-- DaisyUI compatible styles --}}
    <x-rich-text::styles theme="daisyui" />
  3. Use PHP attributes for RichText configuration

    main

    Instead of using the $richTextAttributes property, you can use the #[RichTextAttributes] class attribute. Note that you cannot use both on the same model.

    use Tonysm//\RichTextLaravel\Attributes\RichTextAttributes;
    use Tonysm//\RichTextLaravel\Models\Traits\HasRichText;
    
    #[RichTextAttributes(['body', 'notes'])]
    class Post extends Model
    {
        use HasRichText;
    
        protected $guarded = [];
    }
  4. Create custom non-model attachables

    main

    For attachments that do not require a database record (e.g., OpenGraph embeds), implement AttachableContract on a plain class and register a custom resolver using RichTextLaravel::withCustomAttachables().

    Your class must implement:

    • toRichTextAttributes(array $attributes): array
    • equalsToAttachable(AttachableContract $attachable): bool
    • richTextRender(array $options = []): string

    Use a content-type attribute on the DOM node to identify your custom attachment type.

    // 1. Define the custom attachable class
    class OpengraphEmbed implements AttachableContract
    {
        const CONTENT_TYPE = 'application/vnd.rich-text-laravel.opengraph-embed';
    
        public static function fromNode(DOMElement $node): ?self
        {
            if ($node->getAttribute('content-type') === static::CONTENT_TYPE) {
                return new self(/* attributes from node */);
            }
            return null;
        }
    
        public function richTextRender(array $options = []): string
        {
            return view('attachables.opengraph-embed', ['attachable' => $this])->render();
        }
    
        public function toRichTextAttributes(array $attributes): array
        {
            return [
                'content_type' => static::CONTENT_TYPE,
                'previewable' => true,
            ];
        }
    
        public function equalsToAttachable(AttachableContract $attachable): bool
        {
            return $this->richTextRender() === $attachable->richTextRender();
        }
    }
    
    // 2. Register the resolver in AppServiceProvider::boot()
    RichTextLaravel::withCustomAttachables(function (DOMElement $node) {
        if ($attachable = OpengraphEmbed::fromNode($node)) {
            return $attachable;
        }
    });
  5. Install rich-text-laravel

    main

    Install the package using Composer, run the installation command to set up the package, and then run your migrations to create the necessary database tables.

    composer require tonysm/rich-text-laravel
    php artisan richtext:install
    php artisan migrate
  6. Implement the recommended RichText model structure

    main

    The recommended way to use this package is to store rich text content in a separate rich_texts table rather than on the model's own table. This keeps your primary models lean and allows for eager loading of rich text fields only when needed.

    To implement this, use the HasRichText trait and define your fields in the $richTextAttributes property or via the #[RichTextAttributes] attribute. The trait creates dynamic relationships named richText{FieldName} (e.g., richTextBody for a body field) and adds virtual attributes to the model that forward calls to these relationships.

    use Tonysm//\RichTextLaravel\Models\Traits\HasRichText;
    
    class Post extends Model
    {
        use HasRichText;
    
        protected $guarded = [];
    
        protected $richTextAttributes = [
            'body',
            'notes',
        ];
    }
  7. Store Rich Text directly as a Model Attribute

    main

    If you prefer to store rich text content directly in the model's own table (e.g., in a TEXT column), use the 'attribute' => true option. This bypasses the rich_texts table.

    When using this mode, accessing the field returns a Content instance directly, rather than a RichText model instance. This allows you to call methods like toPlainText() or attachments() directly on the attribute.

    You can mix attribute-based and relationship-based fields on the same model.

    use Tonysm//\RichTextLaravel\Models\Traits\HasRichText;
    
    class Post extends Model
    {
        use HasRichText;
    
        protected $guarded = [];
    
        protected $richTextAttributes = [
            'body' => ['attribute' => true],
            'notes', // Stored in the rich_texts table...
        ];
    }
  8. Make an Eloquent model attachable

    main

    To turn an Eloquent model into a rich text content attachment (like a user mention or embedded resource), the model must implement AttachableContract and use the Attachable trait.

    At a minimum, you must implement the richTextRender() method, which returns the HTML used to display the attachment outside of the editor. You can also optionally implement methods for plain text and markdown exports.

    use Tonysm//RichTextLaravel\Attachables\AttachableContract;
    use Tonysm//RichTextLaravel\Attachables\Attachable;
    
    class User extends Model implements AttachableContract
    {
        use Attachable;
    
        /**
         * Required: Returns the HTML used when displaying the attachment outside the editor.
         */
        public function richTextRender(array $options = []): string
        {
            return view('mentions.partials.user', [
                'user' => $this,
            ])->render();
        }
    
        /**
         * Optional: Implementation for plain text export.
         */
        public function richTextAsPlainText(?string $caption = null): string
        {
            return $this->name;
        }
    
        /**
         * Optional: Implementation for Markdown export.
         */
        public function richTextAsMarkdown(?string $caption = null): string
        {
            return $caption ?: $this->name;
        }
    }
  9. Configure Encrypted Rich Text Attributes

    main

    You can encrypt HTML content at-rest using Laravel's encryption. Specify 'encrypted' => true for specific fields in your configuration.

    protected $richTextAttributes = [
        'body' => ['encrypted' => true],
        'notes',
    ];

    If you need to customize the encryption/decryption logic (e.g., for key rotation or compatibility), use RichTextLaravel::encryptUsing() in your AppServiceProvider::boot() method.

    namespace App//\Providers;
    
    use Illuminate//\Support\Facades\Crypt;
    use Illuminate//\Support\ServiceProvider;
    use Tonysm//\RichTextLaravel\RichTextLaravel;
    
    class AppServiceProvider extends ServiceProvider
    {
        public function boot(): void
        {
            RichTextLaravel::encryptUsing(
                encryption: fn ($value, $model, $key) => Crypt::encrypt($value),
                decryption: fn ($value, $model, $key) => Crypt::decrypt($value),
            );
        }
    }
  10. Install and manage rich-text-laravel via Artisan commands

    main

    The package provides two primary Artisan commands for setup and configuration:

    1. InstallCommand: Used for the initial installation and setup of the package.
    2. SwapCommand: Used to swap or manage existing configurations/implementations.

    Check your terminal for the exact command syntax, typically invoked via php artisan.

  11. Install Rich Text Laravel via CLI

    main

    Use the richtext:install command to set up the package in your Laravel application. This command automates the publishing of migrations and assets, installs the chosen editor frontend (Trix or Lexxy), updates your JavaScript entrypoints, and configures your Blade layouts with the necessary styles.

    During installation, you may be prompted to select a theme (such as daisyui or flux) if the installer detects compatible dependencies or if no default is found.

    php artisan richtext:install