Allow custom data attributes conversion

Created on 26 June 2025, 15 days ago

Problem/Motivation

Sometimes the data attribute conversion doesn't work well or the resulting media embed won't display properly depending on the configuration of the site. For example, the view mode conversion may not work in a case where it was configured to render in a given image style and thus the source view mode is not a valid media entity view mode.

Implementing an alter hook as part of the data attribute conversion function would allow custom modules to hook in and perform conversions appropriate to the site to ensure the desired end result.

Proposed resolution

Add the following to the start of the convertDataAttributes method:

\Drupal::moduleHandler()->alter('convert_entity_media_embed', $value);

This way custom modules can handle some or even all the attribute conversions before any of the current code kicks in.

Feature request
Status

Active

Version

1.0

Component

Code

Created by

🇨🇦Canada teknocat

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @teknocat
  • @teknocat opened merge request.
  • 🇨🇦Canada teknocat

    Having applied the patch from my merge request, here's an example of using an alter hook in a site that uses the CKEditor media resize module. I can check if there's an image style in use, if so load it, get the image width and then use that to set all the appropriate attributes for that module to do its thing. But either way I just remove the data-entity-embed-display attribute because it's never valid anyway in my case, so it just ends up using the default display mode.

    /**
     * Implements hook_convert_entity_media_embed_data_attributes_alter().
     */
    function lwb_base_cms_configuration_convert_entity_media_embed_data_attributes_alter(&$value) {
      if (stristr($value, 'data-entity-embed-display-settings')) {
        // Extract the JSON data from the string.
        preg_match('/data-entity-embed-display-settings="([^"]*)"/', $value, $matches);
        if (isset($matches[1])) {
          $json_data = $matches[1];
          // Decode an html entities, such as ".
          $json_data = html_entity_decode($json_data, ENT_QUOTES | ENT_HTML5, 'UTF-8');
          // Decode the JSON data.
          $data = json_decode($json_data, TRUE);
          if (is_array($data)) {
            $image_style = $data['image_style'] ?? NULL;
            if ($image_style) {
              // If there is an image style specified, load the image style
              // information.
              /**
               * @var \Drupal\image\ImageStyleInterface $image_style
               */
              $image_style = \Drupal::entityTypeManager()->getStorage('image_style')->load($image_style);
              if ($image_style) {
                // If using an image style that scales and/or crops the image, we
                // want to setup the media embed attributes to trigger the
                // ckeditor_media_resize module to resize it accordingly.
                $effects = $image_style->getEffects();
                $image_width = NULL;
                foreach ($effects as $effect) {
                  $effect_config = $effect->getConfiguration();
                  if ($effect_config['id'] === 'image_scale_and_crop' || $effect_config['id'] === 'image_scale') {
                    // Get the final dimensions from the effect.
                    $image_width = $effect_config['data']['width'] ?? NULL;
                  }
                }
                if ($image_width) {
                  $value .= ' class="image_resized"';
                  $value .= ' style="width: ' . $image_width . 'px;"';
                  $value .= ' data-media-width="' . $image_width . 'px"';
                }
              }
            }
          }
        }
      }
      if (stristr($value, 'data-entity-embed-display')) {
        // Either way remove the data-entity-embed-display attribute because we
        // do not want that to be used as a view mode for the entity.
        preg_replace('/ data-entity-embed-display="[^"]*"/', '', $value);
      }
    }
    
Production build 0.71.5 2024