Drupal is a registered trademark of Dries Buytaert

Provides a CKEditor 5 plugin that allows users to convert embedded file-based
images and file links into reusable media entities. This module helps migrate
legacy content from direct file references to Drupal's structured media system
while maintaining content integrity and reducing duplicate files.

Features

  • Adds a "Convert to Media" button to CKEditor 5 toolbar
  • Converts embedded file images (<img> tags) into media entities
    (<drupal-media> elements)
  • Converts file links (<a> tags pointing to files) into media-linked
    references (requires Linkit module)
  • Prevents duplicate media creation by reusing existing entities
  • Provides accessible confirmation dialog
  • Supports multiple file types with automatic media type detection
  • Batch processing functionality to find and convert existing embedded files
    and links
  • Security validation for file types, sizes, and remote downloads

Requirements

  • Drupal 10.0+
  • CKEditor 5
  • Media module
  • Image module
  • File module

Recommended modules

  • Linkit module: Required for file link conversion functionality. Without
    Linkit, only image conversion will work.

Installation

Install as you would normally install a contributed Drupal module. For further
information, see
Installing Drupal Modules.

Via Composer (recommended):

composer require drupal/image_to_media_swapper
drush en image_to_media_swapper

Or download and place in your modules directory, then enable:

drush en image_to_media_swapper

Configuration

  1. Go to Administration > Configuration > Content authoring > Text formats and editors
  2. Edit a text format that uses CKEditor 5
  3. In the toolbar configuration, drag the "Convert to Media" button to your desired position
  4. Save the text format

Ensure your text format allows:

  • <img> tags with src, alt, width, height attributes
  • <drupal-media> tags with data-entity-type, data-entity-uuid,
    data-view-mode attributes

Usage

Converting Images and File Links in CKEditor

  1. For Images: Insert an image into CKEditor 5 content, select it, and click
    the "Convert to Media" button
  2. For File Links: Create a link to a file (requires Linkit module), select
    the link, and click the "Convert to Media" button
  3. Confirm the conversion in the dialog
  4. Images are replaced with <drupal-media> elements, file links are converted
    to media-linked references

Batch Processing

Access the batch conversion tool at: Administration > Configuration > Content
authoring > Image to Media Swapper

  1. Select Fields: Choose text fields containing <img> tags or file links
    to convert
  2. Process Images: Converts embedded image tags to media entities
  3. Process File Links: Converts file links to media-linked references
    (requires Linkit)
  4. Review Results: View processing results and status for each converted
    entity

The batch processor can:

  • Find all entities with embedded images or file links in specified text fields
  • Convert both images and links in a single operation
  • Handle local files, remote files (with security validation), and existing
    file entities
  • Create appropriate media bundles based on file types
  • Track conversion results and errors

Technical Details

API Endpoint

The module provides a secure REST endpoint at /media-api/swap-file-to-media/file-uuid that:

  • Accepts POST requests with a file UUID
  • Creates or returns existing media entities
  • Returns media entity data in JSON format

The second endpoint is /media-api/media-api/swap-file-to-media/local-path which:

  • Accepts POST requests with a filepath value
  • Checks if the file exists in the Drupal file system
  • Checks if the file is already tracked.
  • Creates a new file entity if it does not exist.
  • Checks if the file entity is already associated with a media entity.
  • Creates a new media entity if it does not exist.
  • Returns the media entity data in JSON format.

File Structure

  • src/Controller/SwapperController.php - API controller
  • src/SwapperService.php - Core file and media processing service
  • src/BatchProcessorService.php - Batch processing and field analysis service
  • src/Form/BatchSwapperForm.php - Batch processing form
  • src/SecurityValidationService.php - File security validation
  • js/ckeditor5_plugins/mediaSwapper/ - CKEditor 5 plugin source
  • image_to_media_swapper.ckeditor5.yml - Plugin definition
  • image_to_media_swapper.routing.yml - Route definition

Testing

The module includes comprehensive tests:

# Run all tests
./vendor/bin/phpunit web/modules/contrib/image_to_media_swapper

# Run specific test types
./vendor/bin/phpunit web/modules/contrib/image_to_media_swapper/tests/src/Kernel
./vendor/bin/phpunit web/modules/contrib/image_to_media_swapper/tests/src/FunctionalJavascript

Troubleshooting & FAQ

Button not appearing in toolbar:

  • Verify the text format uses CKEditor 5
  • Check that the button is added to the toolbar configuration
  • Clear Drupal cache: drush cache:rebuild

"No image block with file entity selected" error:

  • Only works with images uploaded through Drupal's file system
  • External images require remote download to be enabled in security settings
  • Ensure the image has proper file entity attributes

File link conversion not working:

  • Ensure Linkit module is installed and enabled
  • Verify the text format supports the required HTML tags and attributes
  • Check that file extensions are supported by your media bundles

Security validation errors:

  • Configure allowed file types in Administration > Configuration > Content
    authoring > Image to Media Swapper Security Settings
  • Adjust maximum file size limits for remote downloads
  • Review allowed/blocked domains for remote file access

Maintainers

Current maintainers:

This project has been sponsored by:

License

This project is licensed under the GPL-2.0+ license.

Activity

Total releases
14
First release
Jul 2025
Latest release
4 months ago
Release cadence
8 days
Stability
71% stable

Release Timeline

Releases

Version Type Release date
2.0.3 Stable Oct 9, 2025
2.0.2 Stable Sep 3, 2025
2.0.1 Stable Aug 7, 2025
2.0.0 Stable Aug 6, 2025
2.x-dev Dev Aug 6, 2025
1.0.5 Stable Jul 23, 2025
1.0.4 Stable Jul 22, 2025
1.0.x-dev Dev Jul 21, 2025
1.0.3 Stable Jul 19, 2025
1.0.2 Stable Jul 13, 2025
1.0.1 Stable Jul 11, 2025
1.0.0 Stable Jul 7, 2025
1.1.0-rc3 Pre-release Jul 7, 2025
1.0.0-rc1 Pre-release Jul 1, 2025