Skip to content

Extend Online Editor

Ibexa DXP users edit the contents of RichText Fields, for example, in the Content box of a Page, by using the Online Editor.

You can extend the Online Editor by adding custom tags and styles, defining custom data attributes, re-arranging existing buttons, grouping buttons into custom toolbar, and creating custom buttons and custom plugins.

Online Editor is based on the CKEditor5. Refer to CKEditor5 documentation to learn how you can extend the Online Editor with even more elements. For more information about extending the Back Office, see Extend Back Office.

Configure custom tags

With custom tags, you can enhance the Online Editor with features that go beyond the built-in ones. You configure custom tags under the ezrichtext key.

Start preparing the tag by adding a configuration file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_tags: [factbox]
                    toolbar:
                        custom_tags_group:
                            buttons:
                                factbox:
                                    priority: 5
ibexa_fieldtype_richtext:
    custom_tags:
        factbox:
            template: '@ibexadesign/field_type/ezrichtext/custom_tags/factbox.html.twig'
            icon: '/bundles/ibexaicons/img/all-icons.svg#information'
            attributes:
                name:
                    type: string
                    required: true
                style:
                    type: choice
                    required: true
                    default_value: light
                    choices: [light, dark]

Custom tags can have as many attributes as needed. Supported attribute types are: string, number, boolean, link, and choice. choice requires that you provide a list of options in the choices key.

You must provide your own files for the Twig template and the icon. Place the factbox.html.twig template in the templates/themes/<your-theme>/field_type/ezrichtext/custom_tags directory:

1
2
3
4
5
6
<div class="ibexa-factbox ibexa-factbox--{{ params.style }}">
    <p>{{ params.name }}</p>
    <div>
        {{ content|raw }}
    </div>
</div>

Tip

If an attribute is not required, check if it is defined by adding a check in the template, for example:

1
2
3
{% if params.your_attribute is defined %}
    ...
{% endif %}

Add labels for the new tag by providing translations in translations/custom_tags.en.yaml:

1
2
3
ezrichtext.custom_tags.factbox.label: 'Factbox'
ezrichtext.custom_tags.factbox.attributes.name.label: 'Name'
ezrichtext.custom_tags.factbox.attributes.style.label: 'Style'

Now you can use the tag. In the Back Office, create or edit a content item that has a RichText Field Type. In the Online Editor, click Add, and from the list of available tags select the FactBox tag icon.

FactBox Tag

Inline custom tags

You can also place custom tags inline with the following configuration:

1
2
3
4
5
6
7
8
ibexa_fieldtype_richtext:
    custom_tags:
        acronym:
            template: '@ibexadesign/field_type/ezrichtext/custom_tags/acronym.html.twig'
            icon: '/bundles/ibexaicons/img/all-icons.svg#edit'
            is_inline: true
            attributes:
                # ...

is_inline is an optional key. The default value is false, therefore, if it is not set, the custom tag is treated as a block tag.

Use cases

You can configure a custom tag with a link attribute that offers a basic UI with text input. It is useful when migrating from eZ Publish to Ibexa DXP.

The configuration is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_tags: [linktag]
                    toolbar:
                        custom_tags_group:
                            buttons:
                                linktag:
                                    priority: 6
ibexa_fieldtype_richtext:
    custom_tags:
        linktag:
            template: '@ibexadesign/field_type/ezrichtext/custom_tags/linktag.html.twig'
            icon: '/bundles/ibexaicons/img/all-icons.svg#link'
            is_inline: true
            attributes:
                title:
                    type: string
                    required: false
                description:
                    type: string
                    required: false
                color:
                    type: choice
                    required: false
                    choices: [Red, Blue, Green]
                url:
                    type: link
                    required: false

Provide your own files for the Twig template and the icon.

The tag has the url attribute with the type parameter set as link (lines 30-31).

Then create the templates/themes/<your-theme>/field_type/ezrichtext/custom_tags/linktag.html.twig template:

1
2
3
4
<h2>Custom link</h2>
{% for attr_name, attr_value in params %}
    <div><strong>{{ attr_name }}</strong>: {{ attr_value }}</div>
{% endfor %}

Add labels for the tag by providing translations in translations/custom_tags.en.yaml:

1
2
3
4
5
ezrichtext.custom_tags.linktag.label: 'Link Tag'
ezrichtext.custom_tags.linktag.attributes.title.label: 'Title'
ezrichtext.custom_tags.linktag.attributes.description.label: 'Description'
ezrichtext.custom_tags.linktag.attributes.color.label: 'Color'
ezrichtext.custom_tags.linktag.attributes.url.label: 'URL'

Now you can use the tag. In the Back Office, create or edit a content item that has a RichText Field Type. In the Online Editor's toolbar, click Show more items, and from the list of available tags select the Link tag icon.

Link Tag

Acronym

You can create an inline custom tag that displays a hovering tooltip with an explanation of an acronym.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_tags: [acronym]
                    toolbar:
                        custom_tags_group:
                            buttons:
                                acronym:
                                    priority: 7
ibexa_fieldtype_richtext:
    custom_tags:
        acronym:
            template: '@ibexadesign/field_type/ezrichtext/custom_tags/acronym.html.twig'
            icon: '/bundles/ibexaicons/img/all-icons.svg#edit'
            is_inline: true
            attributes:
                explanation:
                    type: string

The explanation attribute contains the meaning of the acronym that will be provided while editing in the Online Editor.

Add labels for the tag by providing translations in translations/custom_tags.en.yaml:

1
2
ezrichtext.custom_tags.acronym.label: 'Acronym'
ezrichtext.custom_tags.acronym.attributes.explanation.label: 'Explanation'

Adding an explanation to an Acronym custom tag

In the template file acronym.html.twig provide the explanation as attribute value to the title of the abbr tag:

1
<abbr title="{{ params.explanation }}">{{ content }}</abbr>

Acronym custom tag

Configure custom styles

You can extend the Online Editor with custom text styles. The styles are available in the text toolbar when a section of text is selected.

There are two kinds of custom styles: block and inline. Inline styles apply to the selected portion of text only, while block styles apply to the whole paragraph.

Start creating a custom style by providing configuration:

  • a global list of custom styles, defined under the node ezrichtext.custom_styles,
  • a list of enabled custom styles for a given admin SiteAccess or admin_group SiteAccess group, located under the node ibexa.system.<scope>.fieldtypes.ezrichtext.custom_styles

A sample configuration could look as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_styles: [highlighted_block, highlighted_word]
ibexa_fieldtype_richtext:
    custom_styles:
        highlighted_word:
            template: '@ibexadesign/field_type/ezrichtext/custom_styles/highlighted_word.html.twig'
            inline: true
        highlighted_block:
            template: '@ibexadesign/field_type/ezrichtext/custom_styles/highlighted_block.html.twig'
            inline: false

Note

Currently, if you define these lists for a front site SiteAccess, it has no effect.

Add labels for the new styles by providing translations in translations/custom_styles.en.yaml:

1
2
ezrichtext.custom_styles.highlighted_block.label: Highlighted block
ezrichtext.custom_styles.highlighted_word.label: Highlighted word

Rendering

The template key points to the template that is used to render the custom style. It is recommended that you use the design engine.

The template files for the front end could look as follows:

  • templates/themes/standard/field_type/ezrichtext/custom_styles/highlighted_word.html.twig:
1
<span {% if id is defined %}id="{{ id }}"{% endif %} class="ezstyle-{{ name }}">{% apply spaceless %}{{ content|raw }}{% endapply %}</span>
  • templates/themes/standard/field_type/ezrichtext/custom_styles/highlighted_block.html.twig:
1
<div {% if id is defined %}id="{{ id }}"{% endif %} class="{% if align is defined %}align-{{ align }}{% endif %} ezstyle-{{ name }}">{% apply spaceless %}{{ content|raw }}{% endapply %}</div>

Templates for Content View in the Back Office would be templates/themes/admin/field_type/ezrichtext/custom_styles/highlighted_word.html.twig and templates/themes/admin/field_type/ezrichtext/custom_styles/highlighted_block.html.twig respectively (assuming that the Back Office SiteAccess uses the default admin theme).

Use cases

Note box

You can create a custom style that places a paragraph in a note box:

Example of a note box custom style

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_styles: [note_box]
ibexa_fieldtype_richtext:
    custom_styles:
        note_box:
            template: field_type/ezrichtext/custom_styles/note_box.html.twig

The note_box.html.twig template wraps the content of the selected text ({{ content }}) in a custom CSS class:

1
<div class="note">{{ content }}</div>
1
2
3
4
5
6
7
8
9
.note {
    display: block;
    background-color: #faa015;
    border-left: solid 5px #353535;
    line-height: 18px;
    padding: 15px;
    color: #fff;
    font-weight: bold;
}

Add label for the new style by providing a translation in translations/custom_styles.en.yaml:

1
ezrichtext.custom_styles.note_box.label: 'Note box'

Adding a Note box custom style

Tip

You can also create a similar note box with custom classes.

Text highlight

You can create an inline custom style that highlights a part of a text:

Example of a custom style highlighting a portion of text

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_styles: [highlight]
ibexa_fieldtype_richtext:
    custom_styles:
        highlight:
            template: field_type/ezrichtext/custom_styles/highlight.html.twig
            inline: true

The highlight.html.twig template wraps the content of the selected text ({{ content }}) in a custom CSS class:

1
<span class="highlight">{{ content }}</span>
1
2
3
4
.highlight {
    background-color: #fcc672;
    border-radius: 25% 40% 25% 40%;
}

Add label for the new style by providing a translation in translations/custom_styles.en.yaml:

1
ezrichtext.custom_styles.highlight.label: 'Highlight'

Adding a Highlight custom style

Configure custom data attributes and classes

You can add custom data attributes and CSS classes to the following elements in the Online Editor:

  • embedInline
  • embed
  • formatted
  • heading
  • heading1 to heading6
  • embedImage
  • ul
  • ol
  • li
  • paragraph
  • table
  • tr
  • td

Heading elements

heading applies to all heading elements, and heading1 to heading6 to specific heading levels.

When you configure both heading and a specific heading level (for example, heading2) at the same time, only the more specific configuration applies, in this case, heading2.

Overriding embed templates

If you override the default templates for embedInline, embed or embedImage elements, for example, @IbexaCore/default/content/embed.html.twig, the data attributes and classes will not be rendered automatically.

Instead, you can make use of the data_attributes and class properties in your templates. With the ibexa_data_attributes_serialize helper you can serialize the data attribute array.

Custom data attributes

You configure custom data attributes under the fieldtypes.ibexa_fieldtype_richtext.attributes key. The configuration is SiteAccess-aware.

A custom data attribute can belong to one of the following types: choice, boolean, string, or number. You can also set each attribute to be required and set its default_value.

For the choice type, you must provide an array of available choices. By adding multiple, you can decide whether more than one option can be selected. It is set to false by default.

Use the example below to add two data attributes, custom_attribute and another_attribute to the Heading element in the admin_group SiteAccess:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    attributes:
                        heading:
                            custom-attribute:
                                type: boolean
                                default_value: false
                            another-attribute:
                                type: choice
                                choices: [attr1, attr2]
                                default_value: attr2
                                required: false
                                multiple: true

The configuration outputs data-ezattribute-<attribute_name>="<value>" in the corresponding HTML element. Here, the resulting values are data-ezattribute-custom-attribute="false" and data-ezattribute-another-attribute="attr1,attr2".

Custom CSS classes

You configure custom CSS classes under the fieldtypes.ezrichtext.classes key. The configuration is SiteAccess-aware.

You must provide the available choices. You can also set the values for required, default_value and multiple. multiple is set to true by default.

Use the example below to add a class choice to the Paragraph element in the admin_group SiteAccess:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:                            
                    classes:
                        paragraph:
                            choices: [regular, special, tip_box, warning_box]
                            default_value: regular
                            required: false
                            multiple: false

Label translations

If there are many custom attributes, to provide label translations for these attributes, you can use the ez_online_editor_attributes translation extractor to get a full list of all custom attributes for all elements in all scopes.

For example:

1
2
php ./bin/console translation:extract --enable-extractor=ez_online_editor_attributes
    --dir=./templates --output-dir=./translations/ --output-format=yaml

Use cases

Note box

You can create a custom class that enables you to place a paragraph element in a note box:

Example of a note box custom style

1
2
3
4
5
6
7
8
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:                            
                    classes:
                        paragraph:
                            choices: [regular, special, tip_box, warning_box]

With this class you can choose one of the following classes for each paragraph element: regular, tip_box, or warning_box. You can then style the class by using CSS.

Selecting a custom style for a paragraph

Tip

You can also create a similar note box with custom styles.

Rearrange buttons

You can modify the order and visibility of buttons that are available in the Online Editor toolbar through configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
ibexa:
    system:
        admin_group:
            fieldtypes:
                ezrichtext:
                    custom_tags: [ezyoutube, eztwitter, ezfacebook]
                    toolbar:
                        group1:
                            priority: 60
                            buttons:
                                ibexaMoveUp:
                                    priority: 30
                                ibexaMoveDown:
                                    priority: 20
                                heading:
                                    priority: 10
                        group2:
                            priority: 50
                            buttons:
                                alignment:
                                    priority: 10

For each button you can set priority, which defines the order of buttons in the toolbar.

For a full list of standard buttons, see the RichText module's configuration file

Add CKEditor plugins

Regular CKEditor plugins can be added to the Online Editor. This procedure is illustrated with the addition of the Special characters plugin.

A CKEditor plugin is installed locally by using yarn add or npm install, and is deployed by committing the yarn.lock file. A local installation looks like:

1
yarn add @ckeditor/ckeditor5-special-characters

The CKEditor plugin must be added to the ibexa.richText.CKEditor.extraPlugins array. For this purpose, create an assets/js/richtext.ckeditor-plugins.js to import the plugin elements and add them to the array using ibexa.addConfig :

1
2
3
4
5
// The plugin itself
import SpecialCharacters from '../../node_modules/@ckeditor/ckeditor5-special-characters/src/specialcharacters';
// The character list that will be used by the plugin
import SpecialCharactersEssentials from '../../node_modules/@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials';
ibexa.addConfig('richText.CKEditor.extraPlugins', [ SpecialCharacters, SpecialCharactersEssentials ], true);

The plugin is imported from ../../node_modules/@ckeditor path and not directly from @ckeditor alias because this alias points at ./public/bundles/ibexaadminuiassets/vendors/@ckeditor.

Add the previous file to ibexa-richtext-onlineeditor-js Webpack Encore entry.

Create the following encore/ibexa.richtext.config.manager.js file:

1
2
3
4
5
6
7
8
9
const path = require('path');

module.exports = (ibexaConfig, ibexaConfigManager) => {
    ibexaConfigManager.add({
        ibexaConfig,
        entryName: 'ibexa-richtext-onlineeditor-js',
        newItems: [path.resolve(__dirname, '../assets/js/richtext.ckeditor-plugins.js')],
    });
};

See Importing assets from a bundle for alternative ways to add files to Webpack Encore entries.

Add the plugin button to the RichText toolbar config (under ibexa.system.<scope>.fieldtypes.ezrichtext.toolbar).

A new button group is defined in config/packages/ibexa_admin_ui.yaml with the specialcharacters button exposed by the plugin API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
ibexa:
    # …
    system:
        admin_group:
            # …
            fieldtypes:
                ezrichtext:
                    toolbar:
                        my_group:
                            priority: 25
                            buttons:
                                specialCharacters:
                                    priority: 10

Build the assets and clear the cache by running composer run-script auto-scripts.

For more information, see CKEditor plugins documentation.

Change CKEditor configuration

You can add or override CKEditor configuration to set one of the available properties.

To do it, add a custom config object to the window.ibexa.richText.CKEditor.extraConfig key by using the addConfig method:

1
window.ibexa.addConfig('richText.CKEditor.extraConfig', {your_custom_config_object}, true);

To have Arrows category from previously added Special characters plugin on top of the filter menu:

1
ibexa.addConfig('richText.CKEditor.extraConfig', { specialCharacters: { order: ['Arrows'] } }, true);

CKEditor Special characters: Arrows category on top of the character filter