Weave 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

Ckeditor Widget Bundle Laravel Package

stinger/ckeditor-widget-bundle

A Laravel/PHP package that bundles CKEditor widgets for easy integration. It provides ready-to-use widget assets and configuration to add custom widgets to CKEditor, helping you build richer content editing experiences with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

First, check the framework. stinger/ckeditor-widget-bundle is a Symfony 2 bundle, not a Composer library and not a Laravel package. There is no ServiceProvider, no Facade, no config/*.php to publish, and nothing in the repo that Laravel's container can autoload into a useful state. If you are on Laravel 9+/PHP 8, the composer require will likely fail on symfony/symfony version constraints before you even see the code.

So "getting started" splits into two real paths:

Path 1 — you inherited a Symfony 2 app that already lists it. Look at these files, in this order:

  1. composer.json — note the Symfony/PHP constraints and the autoload PSR-0/PSR-4 mapping. This tells you the bundle namespace (StingerSoft\CKEditorWidgetBundle\StingerSoftCKEditorWidgetBundle style).
  2. DependencyInjection/*Extension.php — this is the entire substance of the bundle. It almost certainly calls prependExtensionConfig() or a container parameter to register the widget plugin path with whichever CKEditor bundle you're also using (Ivory/FOS-style: a plugins: path plus extra_plugins: ['widget']).
  3. Resources/public/ (or Resources/assets/) — the actual CKEditor 4 widget plugin directory (plugin.js, icons/, lang/, dialogs/).
  4. README.md — assume it is a two-line stub; the DI extension is the real documentation.

Register it in app/AppKernel.php (new StingerSoft\CKEditorWidgetBundle\StingerSoftCKEditorWidgetBundle()), run assets:install --symlink, and load a page with a CKEditor instance. Open the browser console and check CKEDITOR.plugins.registered.widget exists.

Path 2 — you're on Laravel and want the capability, not the bundle. The capability is "let editors insert reusable, draggable blocks (callouts, image-with-caption, embeds) into rich text, with a dialog to edit them." The first use case to build is a single callout widget with one dialog field. Do not try to port the bundle; take the plugin files from a CKEditor 4 custom build (or the full CKEditor 4 distribution, which ships widget) and copy plugins/widget plus its dependencies into public/vendor/ckeditor/plugins/.

Implementation Patterns

Pattern A — Symfony DI (what the bundle is for). The bundle's job is one line of config you'd otherwise hand-write. The shape is roughly:

# config.yml — verify against the DI extension, not this snippet
ivory_ck_editor:
    configs:
        default:
            extra_plugins: ['widget']
    plugins:
        widget:
            path: "bundles/stingersoftckeditorwidget/widget/"

The point: one place declares the plugin path and one place adds it to extraPlugins. Every editor instance inherits it. If you find yourself repeating widget in YAML per-form, you've missed the bundle's intent.

Pattern B — Laravel, manual wiring (the realistic path). Put the config in one PHP array, not in twenty Blade views:

// config/ckeditor.php
return [
    'extra_plugins' => ['widget', 'lineutils', 'dialog', 'fakeobjects'],
    'plugin_paths'  => ['widget' => '/vendor/ckeditor/plugins/widget/'],
];

Then one Blade partial or component that emits the config as JSON on a data- attribute and calls CKEDITOR.replaceAll with a callback. Views only ever set data-ckeditor-profile="default".

Pattern C — custom build. CKEditor 4's "Standard"/"Basic" builds do not contain widget or its dependencies. You either use the Online Builder / grunt build from ckeditor-dev with widget included, or copy the plugin dirs from the full package. In a Laravel app with Vite, treat the whole ckeditor/ tree as static assets (publicDir or a copy step) — do not try to bundle plugin.js through the module graph; it sniffs CKEDITOR.plugins.addExternal and absolute script paths.

Pattern D — CKEditor 5, if you're starting fresh. There is no widget plugin in CKEditor 5; the equivalent is a custom plugin using toWidget, toWidgetEditable, an upcast/downcast converter pair, and a schema registration for your container element. Budget a day for what the CKEditor 4 plugin gives you for free.

Pattern E — verification loop. For any of the above: load the editor, confirm CKEDITOR.plugins.registered.widget, insert a widget, save, reload the record. If the widget is no longer draggable/edit-on-double-click after reload, the problem is server-side HTML sanitization, not the plugin — see below.

Gotchas and Tips

  • The dependency chain is the #1 failure. widget requires lineutils, dialog, fakeobjects (and the dialog plugin needs dialogui). If you add only widget to extraPlugins on a standard build, you get a console warning and no widget button — not an exception. Add all four explicitly.
  • ACF will silently eat your widgets. With allowedContent: true everything works; the moment you tighten it you must allow figure, figcaption, div[class], and data-* (extraAllowedContent: 'figure; figcaption; div(!*)[data-*]'). Symptom: widget appears in the editor but saves as plain markup.
  • Round-trip sanitization breaks widgets. CKEditor stores widget state in data-cke-widget-data / data-widget attributes. HTMLPurifier (Laravel's mews/purifier, or any strict allowlist) strips them, so the saved HTML looks fine but is dead on reload. Allowlist data-widget and data-cke-* on the relevant tags, and sanitize after the widget upcast has run — or accept one-way rendering and re-instantiate on the server.
  • Asset paths are the second failure mode. Plugin paths must be root-relative (/vendor/ckeditor/plugins/widget/) or absolute. Symfony's assets:install symlink-vs-copy and Laravel's Vite dev server (different port/origin) both break relative paths that work in production. Test in both vite dev and a built bundle.
  • Symfony 2 only, and abandoned. Last meaningful activity is years stale; it has 1 star and 0 dependents on Packagist. Symfony 4+ removed AppKernel, and bundle inheritance was deprecated — the DI extension as written may not even be loadable. Do not put this on a critical path; vendor the Resources/public plugin directory into your own repo and delete the dependency.
  • Composer 2 / PHP 8. Expect symfony/symfony: ~2.x and php: >=5.3 constraints. You can force with --ignore-platform-reqs for Symfony, but not for Laravel — there is nothing for the framework to boot.
  • Debugging checklist. Browser console for [CKEDITOR] Plugin "widget" not found; CKEDITOR.plugins.registered in the console; confirm extraPlugins is a comma string in CKEditor 4 config (an array is silently coerced in some paths); hard-refresh — CKEditor caches plugin scripts aggressively.
  • License layering. The bundle is MPL-2.0 (file-level copyleft: keep the notices if you vendor files), but the plugin code is CKEditor's, which is GPL/LGPL/commercial triple-licensed. MPL on the wrapper does not relicense the plugin. Check which CKEditor 4 license you're operating under before shipping.
  • Extension points, if you must keep it. In Symfony, fork the DependencyInjection extension — it's ~50 lines and that's the whole bundle. In Laravel, your extension point is the config array plus a Blade component; wrap CKEDITOR.replace so profiles (minimal / full / comment) are config keys, never per-view arguments.
  • Longevity tip. CKEditor 4 is in security-only LTS. If this feature is more than a maintenance concern, prototype the CKEditor 5 custom-element version now and keep the CKEditor 4 path behind a feature flag.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin