close

Filter

loading table of contents...

Studio Developer Manual / Version 2307

Table Of Contents

10.1.3.11 Customizing ckeditorDefault.ts By Example

While in Section 10.1.3.6, “Adapting Existing Configurations” you only got a rough sketch of how to make adjustments to existing configurations, you will now go step-by-step through a possible use case as an example: You will add the Highlight plugin available for CKEditor 5 to the default configuration that ships with CoreMedia Blueprint. To do so, you need to:

For older releases of CoreMedia CKEditor 5 Plugins you will find a section at the end called Compatibility.

See Also

In Section 10.1.3.12, “Providing New CKEditor 5 Configuration By Example” you will see, how to apply this customization only to one single dedicated content property.

Add the Plugin's Dependencies

The Highlight plugin available for CKEditor 5 is part of the @ckeditor/​ckeditor5-highlight package. Thus, within @coremedia-blueprint/​studio-client.​ckeditor5 we add the corresponding dependency:

pnpm add --save-dev "@ckeditor/ckeditor5-highlight@39.0.2"
Caution

Use Fixed Versions for CKEditor 5

In contrast to other dependencies, it is important always only using fixed versions like @39.0.2 for CKEditor 5 dependencies. CKEditor 5 blocks any use of mixed package versions at runtime.

You will notice that when opening a content form in CoreMedia Studio by a missing CKEditor 5 instance and a console error of an uncaught CKEditorError with error code ckeditor-duplicated-modules.

Note

TypeScript Typings

Starting from v35.0.0 first CKEditor 5 packages were developed in TypeScript. Prior to that, typings were only available via DefinitelyTyped. As long as corresponding packages are not migrated to TypeScript, you may want to install the corresponding typings from DefinitelyTyped as @types/​ckeditor__ckeditor5-highlight in this case.

Note, that typings at DefinitelyTyped are not always up-to-date. In these cases one possible option is ignoring these errors with TypeScript @ts-expect-error annotation. This will also automatically tell you at compile time, when typings got updated accordingly.

Add the Plugin

Next, you add the plugin to ckeditorDefault.ts in package @coremedia-blueprint/​studio-client.​ckeditor5 and extend the toolbar accordingly:

import { Highlight } from "@ckeditor/ckeditor5-highlight";

/* ... */

const defaultToolbarItems = [
  /* ... */
  "superscript",
  "highlight",
  "removeFormat",
  /* ... */
];

return ClassicEditor.create(domElement, {
  /* ... */
  plugins: [
    /* ... */
    Highlight,
    /* ... */
  ],
});

/* ... */

Of course, you may also adapt the configuration of the plugin within ckeditorDefault.ts. For this example we stick to the default configuration (which is applying no extra configuration).

Configure Data-Processing

As documented for the Highlight plugin, it uses inline <mark> element. As described in Section 10.1.1.2, “Design Principle: HTML First” you will not change that, neither for editing view nor for data view (see Section 10.1.1.1, “Glance at CKEditor 5 Architecture” to get to know about the various layers). Instead, you have to adapt your data-processing, as CoreMedia Rich Text 1.0 does not support the <mark> element.

Extend the data-processing as follows:

import { replaceElementByElementAndClass } from
  "@coremedia/ckeditor5-coremedia-richtext";

/* ... */

return ClassicEditor.create(domElement, {
  /* ... */
  plugins: [
    /* ... */
    Highlight,
    /* ... */
  ],
  "coremedia:richtext": {
    rules: [
      // Highlight plugin support.
      replaceElementByElementAndClass({
        viewLocalName: "mark",
        dataLocalName: "span",
        // "mark" is the default here, derived from `viewLocalName`. Thus,
        // we may skip it here.
        dataReservedClass: "mark",
      }),
    ],
  },
});

/* ... */

As you see it uses a method replaceElementByElementAndClass available from @coremedia/​ckeditor5-coremedia-richtext. This method covers a typical use case when it comes to identifying a representation of an HTML element in CoreMedia Rich Text 1.0: It maps the <mark> element to a corresponding representation as <span> with identifying class attribute value and vice versa.

Thus, if you highlighted some text with green background:

<mark class="marker-green">Highlight me</mark>

It will be transformed in CoreMedia Rich Text 1.0 data via data-processing to:

<span class="mark marker-green">Highlight me</span>

Note, that replaceElementByElementAndClass is only a shorthand function for a slightly more complex, but also more versatile, mapping you could apply. To get to know more about possible configuration options of the data-processing for CoreMedia Rich Text 1.0, have a look at Section 10.1.2.7, “Rich Text Plugin”.

Adapt CSS Styling

Luckily CSS styles provided by CKEditor 5 and its plugins also directly apply to CKEditor 5 instances in CoreMedia Studio. Thus, to support, for example, the class marker-green as sketched in the previous step, there is nothing which needs to be done, to make the default style work in CoreMedia Studio. But perhaps, the Green is not Green enough? Just apply this SCSS snippet to your CoreMedia Studio styling:

.ck-content {

  .marker-green {
    background-color: #00ff00;
  }

  /* ... */
}

For details, have a look at Section 9.16.1, “Blueprint Studio Theme”.

Adapt Delivery

Of course, adapting CoreMedia Studio and the CKEditor 5 configuration is only half of the way to take. Depending on the technology you use for delivery, you now have to apply most likely the same mapping from:

<span class="mark marker-green">Highlight me</span>

to:

<mark class="marker-green">Highlight me</mark>

unless you are satisfied applying just some additional CSS-rules for the <span> element.

Thus, you may want to have a look at one of these manuals:

  • Section 4.3.4.1, “Rendering Markup” in Content Application Developer Manual

    More specifically, in CoreMedia Blueprint, you may want to adapt BlueprintRichtextFiltersConfiguration providing a corresponding instance of XMLFilter. For this use-case you may extend the configuration of bean reservedClassToElementFilter as shown in Example 10.19, “Adapting Bean reservedClassToElementFilter”.

    @Bean
    ReservedClassToElementFilter reservedClassToElementFilter() {
      return new ReservedClassToElementFilter(List.of(
        // <span class="mark"> -> <mark>
        ReservedClassToElementConfig.of("span", "mark", "mark"),
        /* … */
      ));
    }
    

    Example 10.19. Adapting Bean reservedClassToElementFilter


  • Frontend Developer Manual

    More specifically, in CoreMedia Blueprint, you may want to adapt variables/_coremedia-richtext-1.0.scss and partials/_coremedia-richtext-1.0.scss in @coremedia/brick-utils as shown in Example 10.20, “Adapting variables/_coremedia-richtext-1.0.scss” and Example 10.21, “Adapting partials/_coremedia-richtext-1.0.scss”.

    /* Same Colors as CKEditor 5 Highlight Plugin by default */
    $cm-richtext-mark-marker-yellow: hsl(60, 97%, 73%) !default;
    $cm-richtext-mark-marker-green: hsl(120, 93%, 68%) !default;
    $cm-richtext-mark-marker-pink: hsl(345, 96%, 73%) !default;
    $cm-richtext-mark-marker-blue: hsl(201, 97%, 72%) !default;
    $cm-richtext-mark-pen-red: hsl(0, 85%, 49%) !default;
    $cm-richtext-mark-pen-green: hsl(112, 100%, 27%) !default;
    

    Example 10.20. Adapting variables/_coremedia-richtext-1.0.scss


    mark {
      &.marker-yellow {
        background-color: $cm-richtext-mark-marker-yellow;
        color: inherit;
      }
    
      &.marker-green {
        background-color: $cm-richtext-mark-marker-green;
        color: inherit;
      }
    
      &.marker-pink {
        background-color: $cm-richtext-mark-marker-pink;
        color: inherit;
      }
    
      &.marker-blue {
        background-color: $cm-richtext-mark-marker-blue;
        color: inherit;
      }
    
      &.pen-red {
        background-color: transparent;
        color: $cm-richtext-mark-pen-red;
      }
    
      &.pen-green {
        background-color: transparent;
        color: $cm-richtext-mark-pen-green;
      }
    }
    

    Example 10.21. Adapting partials/_coremedia-richtext-1.0.scss


  • Chapter 5, Rich Text in Headless Server Manual

    More specifically, in CoreMedia Blueprint, you may want to adapt the existing default view configuration in headless-server-base, first by declaring the reserved class mark as shown in Example 10.22, “Adapting richtext/includes/classes.yml” and then by defining the mapping as shown in Example 10.23, “Adapting richtext/default.yml”.

    classes:
      - &inline_styles !!java.util.ArrayList
        # ...
        - &mark_style      mark
    

    Example 10.22. Adapting richtext/includes/classes.yml


    handlerSets:
      text: &text_handlers
        - !Handler
          eventMatcher: !Matcher {qname: *span, classes: *inline_styles}
          outputHandler:
            !ElementWriter
            # ...
            elementTransformer:
              !ElementFromClass
              mapping:
                # ...
                *mark_style: mark
    

    Example 10.23. Adapting richtext/default.yml


Compatibility

Configuration of coremedia:richtext provides compatibility modes for rule parsing. The default compatibility mode is latest. Find below enumerated compatibility modes and the corresponding configuration.

v10

Version 11 of CoreMedia CKEditor 5 Plugins introduced a new way to configure data-processing. While originally using object-style definitions in version 10, with rather limited DOM manipulation support, version 11 comes with array-style definition and rich DOM manipulation support.

You may switch back to the old behavior by setting compatibility to v10 in configuration. The example shown in Section “Configure Data-Processing” will look like given in the following example then:

import { replaceByElementAndClassBackAndForth } from
  "@coremedia/ckeditor5-coremedia-richtext/src/compatibility/v10/rules/ReplaceBy";

/* ... */

return ClassicEditor.create(domElement, {
  /* ... */
  plugins: [
    /* ... */
    Highlight,
    /* ... */
  ],
  "coremedia:richtext": {
    compatibility: "v10",
    rules: {
      elements: {
        // Highlight Plugin Support
        mark: replaceByElementAndClassBackAndForth("mark", "span", "mark"),
      },
    },
  },
});

/* ... */

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.