DrupalElementStyle: Add styles to drupal-media in CKEditor 5 using only configuration

With Drupal’s upgrade to CKEditor 5, users can now add their own attributes or styles to the media toolbar using the new DrupalElementStyle plugin via YAML definitions …without writing a single line of JavaScript!

Let’s look at an example where we want to add options for an attribute called data-attribution as  ‘in-house’, ‘external’, and ‘none’ in the media toolbar. Create a file in your module’s root named mymodule.ckeditor5.yml with the following:

  provider: mymodule
      - drupalMedia.DrupalElementStyle
          - name: 'in-house'
            title: 'In house'
            attributeName: 'data-attribution'
            attributeValue: 'in-house'
            modelElements: [ 'drupalMedia' ]
            icon: '<svg>in_house_icon</svg>'
          - name: 'external'
            title: 'External source'
            attributeName: 'data-attribution'
            attributeValue: 'external'
            modelElements: [ 'drupalMedia' ]
            icon: '<svg>external_icon</svg>'
          - name: 'none'
            title: 'Unknown'
            isDefault: true
            modelElements: [ 'drupalMedia' ]
            icon: '<svg>unknown_icon</svg>'
          - '|'
          - 'drupalElementStyle:attribution:none'
          - 'drupalElementStyle:attribution:in-house'
          - 'drupalElementStyle:attribution:external'
          - '|'
    label: Media attribution
      - <drupal-media data-attribution>
      plugins: [media_media]

Under the ckeditor.plugins key we specify that this requires the DrupalElementStyle plugin in the drupalMedia package. Next we provide configuration for this plugin, at ckeditor5.config.drupalElementStyles. We choose a unique key to represent this new capability — and since it's about source attribution, we go with attribution.

The array of 3 possible choices define 3 unique attribute values, all on a new attribute to be set when using this plugin: data-attribution. See the documentation in the DrupalElementStyleEditing plugin for the expected structure.

The drupal.toolbar configuration is responsible for how the toolbar is displayed. Each item is listed in the form of ‘drupalElementStyle', the name of the attribute, and the value of the attribute, all separated by a semi-colon. Later we will show how to display the toolbar as a list dropdown or splitbutton.

Finally, under drupal.elements we declare that this plugin can generate the data-attribution attribute on <drupal-media> elements (which will cause the "Limit allowed HTML tags and correct faulty HTML" filter to get configured correctly!). But this plugin can't create <drupal-media> elements, the media_media plugin can! So we make that plugin a condition for this plugin to be enabled.

And because that's the only condition we define, this plugin actually gets enabled automatically as soon as the Media (media_media) plugin is enabled.

If we save the Text Editor using the Media plugin with our new CKEditor 5 plugin available, and we then go to a form using that Text Editor, you can now see the buttons for the unknown, in-house, and external attribute in the media toolbar with their SVG icon.

After clicking on the in-house button, the data-attribution is added to the markup.

The above configuration will display as individual buttons in the toolbar because the display key is omitted. However you can also specify either display: ‘listDropdown’ ordisplay: ‘splitButton’ like so by changing the value of the toolbar key:

          - name: 'drupalMedia:attribution'
            display: 'listDropdown'
              - 'drupalElementStyle:attribution:in-house'
              - 'drupalElementStyle:attribution:external'
              - 'drupalElementStyle:attribution:none'
            defaultItem: 'drupalElementStyle:attribution:in-house'

Thanks to the new DrupalElementStyle plugin, you can add your own custom styling to the media toolbar without a single line of JS.

Check out this blog post by @hugronaphor https://cornel.co/article/extend-drupalmedia-ckeditor5-plugin-additional-configurations for another example and special thanks to Wim Leers for helping with this blog post.