Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ux Quill Laravel Package

ehyiah/ux-quill

Symfony UX bundle integrating the Quill.js WYSIWYG editor. Add QuillType to your forms (works well with EasyAdmin), supports AssetMapper or Webpack Encore builds, and includes simple Twig patterns to render saved HTML with Quill styling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require ehyiah/ux-quill
    

    For AssetMapper users, no further steps are needed. For Webpack Encore, run:

    yarn install --force && yarn watch
    

    or

    npm install --force && npm run watch
    
  2. First use case: Add a WYSIWYG field to a Symfony form.

    // src/Form/PostType.php
    use Ehyiah\QuillJsBundle\Form\QuillType;
    
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('content', QuillType::class);
    }
    
  3. Render the content in Twig:

    {{ quill_content_styles() }} {# Required for AssetMapper #}
    <twig:QuillContent value="{{ post.content }}" />
    

    For inline styling (no Quill CSS):

    <twig:QuillContent value="{{ post.content }}" style="inline" />
    

Implementation Patterns

Core Workflows

1. Form Integration

  • Basic Field:
    $builder->add('bio', QuillType::class, [
        'label' => 'About Me',
        'placeholder' => 'Write your story...',
    ]);
    
  • Custom Toolbar:
    $builder->add('description', QuillType::class, [
        'quill_options' => [
            'toolbar' => [
                ['bold', 'italic'], // Groups
                ['clean'],          // Separator
                ['link', 'image'],  // Fields
            ],
        ],
    ]);
    
  • Readonly Mode (for display-only):
    $builder->add('terms', QuillType::class, [
        'readonly' => true,
    ]);
    

2. EasyAdmin Integration

// src/Entity/PostCrudController.php
use Ehyiah\QuillJsBundle\Form\QuillAdminField;

public function configureFields(string $pageName): iterable {
    yield QuillAdminField::new('content')
        ->setLabel('Article Content')
        ->setQuillOptions([
            'modules' => ['history', 'toolbar'],
        ]);
}

3. Dynamic Content Rendering

  • With Quill CSS (default):
    <div class="ql-snow">
        <div class="ql-editor">
            {{ post.content|raw }}
        </div>
    </div>
    
  • Inline (no CSS):
    <div>{{ post.content|raw }}</div>
    

4. Stimulus Customization

Extend Quill behavior via Stimulus controllers:

// assets/controllers/quill_controller.js
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
    connect() {
        this.application.register('quill', QuillJsBundle.QuillController);
        this.quill.on('text-change', () => {
            console.log('Content changed!');
        });
    }
}

PHP Configuration:

$builder->add('notes', QuillType::class, [
    'quill_controller' => 'custom-quill',
]);

5. Image Uploads

Configure a custom upload endpoint:

$builder->add('article', QuillType::class, [
    'upload_endpoint' => '/api/upload',
    'upload_options' => [
        'headers' => ['Authorization' => 'Bearer token123'],
    ],
]);

Backend Route (Symfony):

# config/routes.yaml
api_upload:
    path: /api/upload
    controller: App\Controller\UploadController::upload
    methods: POST

6. Modules and Extensions

  • Enable Built-in Modules:
    $builder->add('editor', QuillType::class, [
        'modules' => ['history', 'markdown', 'imageGallery'],
    ]);
    
  • Custom PHP Module (e.g., ReadingTime):
    use Ehyiah\QuillJsBundle\Form\QuillFieldModuleInterface;
    
    class ReadingTimeModule implements QuillFieldModuleInterface {
        public function getName(): string { return 'readingTime'; }
        public function getConfig(): array { return []; }
    }
    
    Register in QuillType options:
    $builder->add('content', QuillType::class, [
        'modules' => [new ReadingTimeModule()],
    ]);
    

Integration Tips

  1. AssetMapper vs. Webpack Encore:

    • AssetMapper: Zero config for static assets. Use quill_content_styles() in Twig.
    • Webpack Encore: Ensure yarn watch is running. Import Quill CSS in your entrypoint:
      // assets/app.js
      import 'quill/dist/quill.snow.css';
      
  2. Sanitization: Use Symfony’s built-in sanitizer for form data:

    // src/Controller/PostController.php
    use Symfony\Component\HtmlSanitizer\SanitizerInterface;
    
    public function update(Request $request, SanitizerInterface $sanitizer) {
        $data = $request->request->all();
        $data['content'] = $sanitizer->sanitize($data['content']);
        // ...
    }
    
  3. Live Components: For Turbo/Stimulus Live Components, ensure the Quill instance is reinitialized:

    // assets/controllers/quill_live_controller.js
    import { Controller } from '@hotwired/stimulus';
    
    export default class extends Controller {
        connect() {
            this.quill = QuillJsBundle.QuillController.init(this.element);
        }
        disconnect() {
            this.quill.quill?.destroy();
        }
    }
    
  4. EasyAdmin Asset Mapping: Add Quill assets to EasyAdmin’s AssetMapper:

    // src/Admin/AppAdmin.php
    public static function getAssetMapper(): AssetMapper {
        $assetMapper = parent::getAssetMapper();
        $assetMapper->addEntry('quill-css', 'bundles/quilljs/dist/quill.snow.css');
        return $assetMapper;
    }
    

Gotchas and Tips

Pitfalls

  1. Table Module Issues:

    • Problem: The table module may not render correctly if initial content is set in Twig (deprecated in v3+).
    • Fix: Use JavaScript hydration (handled automatically by the bundle). Ensure your form passes raw HTML:
      $post->setContent('<table>...</table>');
      
  2. Asset Loading Race Conditions:

    • Problem: Quill may fail to initialize if CSS/JS isn’t loaded before Stimulus connects.
    • Fix: Use data-controller="quill" on the form field and ensure quill_content_styles() is called in the parent template.
  3. Sanitization Conflicts:

    • Problem: Double sanitization (e.g., custom sanitizer + Symfony’s) may strip valid HTML.
    • Fix: Disable sanitize_html in QuillType options and rely on Symfony’s default sanitizer:
      $builder->add('content', QuillType::class, [
          'sanitize_html' => false, // Let Symfony handle it
      ]);
      
  4. EasyAdmin Styling:

    • Problem: Quill’s CSS may not apply in EasyAdmin due to scoped styles.
    • Fix: Use !important in your CSS or override EasyAdmin’s styles:
      /* assets/css/easyadmin.css */
      .easyadmin-field-quill .ql-snow {
          all: initial !important;
      }
      
  5. Module Initialization Order:

    • Problem: Custom modules may fail if Quill isn’t fully initialized.
    • Fix: Use the hydrate:before event to inject modules:
      // assets/controllers/quill_controller.js
      connect() {
          this.quill.on('hydrate:before', (quill) => {
              quill.register('modules/readingTime', ReadingTimeModule);
          });
      }
      
  6. Turbo/Stimulus Conflicts:

    • Problem: Quill instances may not persist during Turbo navigation.
    • Fix: Use data-turbo-permanent on the form or reinitialize in turbo:load:
      document.addEventListener('turbo:load', () => {
          QuillJsBundle.QuillController.initAll();
      });
      

Debugging Tips

  1. Check Stimulus Logs: Enable Stimulus debugging to see initialization errors:
    // assets/app.js
    import { Application } from '@hot
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle