Data-align value unavailable in filters for CKEditor 5 previews

Created on 13 December 2023, 7 months ago
Updated 4 March 2024, 4 months ago

Problem/Motivation

We've customized the display of embedded images. We have a custom HTML filter process() function that uses the value of the <drupal-entity data-align="" attribute to set specific display modes and add certain CSS classes to embedded images to achieve our desired appearance images according to their set alignment. We're running into challenges migrating to CKEditor 5 because the data-align attribute is being removed from the element when rendered within CKEditor (i.e. while editing the content), therefore the images in the editor don't have the correct display mode or CSS classes set so they appear different in the editor than they do when rendered on the actual page.

The removal of the data-align attribute appears to be intentional and was introduced in this commit https://git.drupalcode.org/project/entity_embed/-/merge_requests/12/diff... As I understand it, it was removed because the alignment is set on the container element in the editor preview, but the container element is not available in the filter process() function when called to render the editor preview. So any filter that uses the data-align value will not work in the CKEditor 5 preview unless there is a workaround that I'm unaware of.

Steps to reproduce

1. Create and enable a HTML filter in your CKEditor 5 text format configuration.
2. Embed an image within a page, select an alignment option for the image, and save the page.
3. You'll see that when the page is rendered, if you debug the filter's process() function that the HTML in the $text parameter that is passed to the function will contain a <drupal-entity> element with a data-align attribute set to the selected alignment value.
4. Edit the page and if you debug the process() function when it gets called to render the image inside of the WYSIWYG editor, you'll see that the data-align attribute is missing from the $text parameter that is passed to the process() function. The container element (where the alignment is set within the editor preview) is not passed to the function so it cannot perform any action on the alignment value.

Proposed resolution

Provide some way for a HTML filter process() function to access the alignment value of embedded images when those images are rendered within the CKEditor 5 preview.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Needs review

Version

1.0

Component

CKEditor integration

Created by

πŸ‡ΊπŸ‡ΈUnited States RichardDavies Portland, Oregon

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

Comments & Activities

  • Issue created by @RichardDavies
  • πŸ‡ΊπŸ‡ΈUnited States RichardDavies Portland, Oregon
  • Status changed to Needs review 5 months ago
  • Here's the most straight-forward solution I could come up with (patch attached).

    This patch: Passes a boolean to the CKEditor 5 plugin of whether the Drupal core alignment filter is enabled. If it's disabled (i.e. we can safely assume that the `data-align` attribute is unused unless the site has a custom filter enabled), then we don't add data-align to the attribute ignore list so that any custom filters can handle it.

    Another option would be to simply rename the attribute to `data-removed-align` or something rather than removing it completely, but that would require the filter to check both attributes and seems more convoluted overall.

    Any input appreciated, thanks.

  • πŸ‡ΊπŸ‡ΈUnited States bkosborne New Jersey, USA

    I've run into this as well, but note that I do use core's FilterAlign text filter. But what I do is alter the embed like this:

    
    function HOOK_entity_embed_alter(array &$build, EntityInterface $entity, array &$context) {
      // Pass the data-align attribute down to the entity render data, because
      // we want the alignment classes added to the HTML for the entity and not
      // the "container" div that entity embed wraps it in. In fact, we remove that
      // container div entirely via a template override in ps_base theme because
      // we don't want the extra markup.
      // No need to mess with cache key, since embedded entities are already not
      // cached.
      // Note that since the FilterAlign filter runs before this code, it has
      // already set the alignment class, so we need to check for it there instead
      // of from the data attribute.
      foreach (['align-left', 'align-center', 'align-right'] as $alignmentClass) {
        if (isset($context['class']) && in_array($alignmentClass, $context['class'])) {
          $build['entity']['#attributes']['class'][] = $alignmentClass;
        }
      }
    }
    

    So I run into the same problem, in that when the embed is being previewed within the editor, this code doesn't actually have any alignment class to work with as the CKE plugin removed it for the preview. Things do work fine otherwise though.

    I think for now, I'm just going to try and hack around this with my ckeditor5-stylesheet, but not ideal.

Production build 0.69.0 2024