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 Sonata Media Bundle Laravel Package

tilleuls/ckeditor-sonata-media-bundle

Symfony bundle that integrates CKEditor with Sonata Media, letting editors browse and insert images and files from the Sonata Media library directly through a CKEditor toolbar button, with configurable Sonata admin integration for seamless media embedding.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is thin glue: it exposes SonataMediaBundle's media library and upload pipeline to CKEditor 4's "file browser" popup. It does not replace SonataMediaBundle, and it does not provide an editor itself — you still need SonataMediaBundle (with at least one context and provider configured) and a CKEditor bundle such as egeloen/ivory-ckeditor-bundle or its successor friendsofsymfony/ckeditor-bundle.

Prerequisites checklist

  • sonata-project/media-bundle installed, configured with a filesystem/CDN, at least one provider (sonata.media.provider.image), and at least one context.
  • A working upload directory and sonata_media formats defined (e.g. small, medium, reference), because the browse popup renders thumbnails using a named format.
  • A CKEditor integration bundle registered and rendering ckeditor form types.
  • Symfony firewall/session working — the browse popup loads in a new window and relies on the current session.

Install and wire up

composer require tilleuls/ckeditor-sonata-media-bundle

Register the bundle (manually in config/bundles.php on Symfony 4+, or AppKernel on older apps):

// config/bundles.php
return [
    // ...
    CoopTilleuls\Bundle\CKEditorSonataMediaBundle\CoopTilleulsCKEditorSonataMediaBundle::class => ['all' => true],
];

Import the bundle routes — this is the step people most often forget:

# config/routes/coop_tilleuls_ckeditor_sonata_media.yaml
coop_tilleuls_ckeditor_sonata_media:
    resource: "@CoopTilleulsCKEditorSonataMediaBundle/Resources/config/routing.xml"
    prefix: /ckeditor

Point your CKEditor config at the two routes it provides (..._browse and ..._upload). With IvoryCKEditorBundle:

# config/packages/ivory_ck_editor.yaml
ivory_ck_editor:
    configs:
        default:
            filebrowserBrowseRoute: coop_tilleuls_ckeditor_sonata_media_browse
            filebrowserBrowseRouteParameters: { context: default, format: small }
            filebrowserUploadRoute: coop_tilleuls_ckeditor_sonata_media_upload
            filebrowserUploadRouteParameters: { context: default }

With FOSCKEditorBundle the keys are the same but under fos_ck_editor. After that, clear the cache, publish assets (bin/console assets:install --symlink), and click the "Browse Server" button in CKEditor's Image dialog.

Where to look first

  • Resources/config/routing.xml inside the bundle — confirms the exact route names and URL parameters (context, format) the controller expects.
  • The bundle's Controller/ directory — shows how browse and upload select a context and build the media query.
  • The Resources/views/ templates — the browse grid is a Twig template you can override to match your admin theme.

First use case: give content editors an "Insert image from media library" workflow — open the image dialog, browse existing Sonata media filtered to the default context, or upload a new file without leaving the editor.

Implementation Patterns

One CKEditor config per content context. The bundle's real value is filtering media by Sonata context. Create a config per editorial area so editors only see relevant assets:

ivory_ck_editor:
    configs:
        article:
            filebrowserBrowseRoute: coop_tilleuls_ckeditor_sonata_media_browse
            filebrowserBrowseRouteParameters: { context: article, format: medium }
            filebrowserUploadRoute: coop_tilleuls_ckeditor_sonata_media_upload
            filebrowserUploadRouteParameters: { context: article }
        homepage:
            filebrowserBrowseRoute: coop_tilleuls_ckeditor_sonata_media_browse
            filebrowserBrowseRouteParameters: { context: homepage, format: wide }

Then reference the config in your form type ('config_name' => 'article').

Control the thumbnail size via format. format is a Sonata media format name, not a pixel value. Define the formats you want in sonata_media and reuse them in filebrowserBrowseRouteParameters. If the format does not exist, the grid renders without thumbnails or throws when generating the cache.

Uploads inherit the context from the route parameters. The upload action creates media in the context passed in the URL. Use the same context for browse and upload, otherwise newly uploaded files won't appear in the browser you opened.

Override the browse template to align with your admin skin. Copy the bundle template into templates/bundles/CoopTilleulsCKEditorSonataMediaBundle/... (Symfony 4+) or app/Resources/CoopTilleulsCKEditorSonataMediaBundle/views/... (Symfony 3) and adjust the markup. Keep the JavaScript that calls window.opener.CKEDITOR.tools.callFunction(...) intact — that's the handshake with the editor.

Add access control and ACL scoping in a wrapper controller. The bundle's browse action queries Sonata media directly; it does not apply SonataAdmin ACL rules or per-user restrictions. For anything multi-tenant, override the browse route to point at your own controller that filters by owner/context and reuses the bundle's template:

# config/routes/coop_tilleuls_ckeditor_sonata_media.yaml
coop_tilleuls_ckeditor_sonata_media_browse:
    path: /ckeditor/browse
    controller: App\Controller\CkEditorMediaController::browse
    methods: [GET]

Lock down the routes. They are normal Symfony routes and need explicit protection. Add an access_control entry requiring an authenticated admin role for your /ckeditor prefix:

security:
    access_control:
        - { path: ^/ckeditor, roles: ROLE_ADMIN, requires_channel: https }

Use it inside Sonata Admin forms. Combine with the Ivory/FOS CKEditor form type in an admin class; editors then get the same media browser inside the admin panel. Keep the CKEditor config name consistent between the admin form and the front-end forms so behavior doesn't diverge.

Handle upload responses in the popup. The upload action returns an HTML page that runs JavaScript to insert the selected/uploaded media into the parent editor. If you customize the upload template, preserve the CKEditorFuncNum handling from the original.

Gotchas and Tips

  • CKEditor 5 is not supported. This bundle targets CKEditor 4's file-browser API (filebrowserBrowseUrl, CKEditorFuncNum). CKEditor 5 dropped that model; you need a custom build with a media-library plugin instead.
  • Route names are easy to mistype. Run bin/console debug:router | grep ckeditor and verify both browse and upload routes exist with your prefix. A missing routing import produces a silent "file browser not available" error in the popup.
  • Context mismatch produces empty libraries. If context: article is passed but no media exists in that Sonata context (or the context isn't declared in sonata_media.contexts), the browser shows an empty grid. Verify the context in config/packages/sonata_media.yaml.
  • Formats must exist. The format parameter must match a key under sonata_media.formats. Otherwise thumbnail generation fails or returns a broken image; check var/log and the media cache directory.
  • Don't hardcode query strings. CKEditor appends its own parameters (CKEditor, CKEditorFuncNum, langCode) to the browse URL. Use filebrowserBrowseRouteParameters / filebrowserUploadRouteParameters rather than putting ?context=... in a URL.
  • Popup sessions and SameSite cookies. The browse window is a separate window load; if your session cookie is SameSite=Strict or your firewall redirects to login inside the popup, the editor appears to hang. Test browse URLs directly in a browser tab while logged in.
  • Upload limits come from two places. PHP's upload_max_filesize/post_max_size and Sonata Media's per-provider max_size/allowed extensions. A rejected upload often returns a valid-looking page with no image — inspect the popup's HTML and the server log.
  • Check CSRF handling on upload. The upload flow is form-based; if your firewall or a custom template expects a CSRF token, verify the bundle's upload form includes and validates one before exposing the route broadly.
  • ACL is not inherited. The bundle does not enforce Sonata's sonata.media.security.* strategies. In multi-user setups, wrap or replace the controller; otherwise every editor can see every asset in the context.
  • IvoryCKEditorBundle is abandoned. For new projects use FOSCKEditorBundle (fos_ck_editor) — same route options, but package names and bundle registration differ. Don't mix config roots.
  • Version compatibility is the biggest risk. The last release was November 2023 and activity is low; pin Symfony, Sonata Media, and Twig versions in composer.json and run the browse/upload flow after every upgrade. Check the bundle's own composer.json constraints before assuming Symfony 6/7 support.
  • Template override caching. After copying a browse template into templates/bundles/..., run bin/console cache:clear; Twig's bundle override resolution won't pick it up otherwise.
  • Debugging checklist: open the browse URL directly (/ckeditor/browse?context=default&format=small), inspect the popup for JS errors, check debug:router, confirm the media manager returns items in a small command or test, then verify the CKEditor filebrowser* keys actually land in the generated editor config (view source).
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console