A CKEditor with an embedded image
The source of CKEditor showing that the image is a tracked image entity.
The conversion dialog asking for confirmation with Yes or Cancel.
The same photo now as a media entity.
The source of the CKEditor HTML showing a tracked media entity.
A select element with two entities listed for conversion to text links.
Select element with a single entity listed for image conversion
Results of conversions list in a group of nested tables.

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.

Supporting organizations: 
Paid for development

Project information

Releases