• Document Up to Date
  • Updated On 4.2.0

Rich Text Editor Configuration

RTEs are more effective/productive for authors when they are configured properly for the specific type of content the author is managing. A properly and effectively configured RTE has the right styles, menu options and so on. Every RTE in the system can have a different look and feel, different editing/menu options, available styles, components and other configurations. You can also SHARE setups between similar RTEs in your project.

This document describes how to configure various configuration options and plugins for the RTE in the User Interface Configuration file.

Common Configurations for Effective RTEs

Here are some things to consider for setting up effective RTEs:

  1. The rich text editor’s width should be set to the same width as the region it is intended to edit

  2. Project style sheet of your project is imported so it can be applied to the RTE

  3. Project styles are being applied appropriately to the markup in the RTE. Note that sometimes styles in CSS are so aggressively specified that the RTE cannot pick them up.

  4. Formats and styles are configured to match the part of the project being edited

  5. Toolbar is configured with only what is required for the specific use case (reducing options makes it easier for editors)

  6. If plugins like insert layout and so on are enabled it should be fully configured.


What Out-of-the-Box Functionality Does Crafter Studio’s RTE Support?

Our RTE is based on TinyMCE 7 (https://www.tiny.cloud/) and can leverage all configurations and plugins designed for the TinyMCE editor. You can find the documentation for these TinyMCE configurations and settings here: https://www.tiny.cloud/docs/

TinyMCE plugins

Crafter Studio uses standard TinyMCE plugins. To see the list of TinyMCE plugins available in Studio, look for plugins in the configuration:

CRAFTER_HOME/data/repos/sites/SITENAME/sandbox/config/studio/ui.xml
<widget id="craftercms.components.TinyMCE">
  <configuration>
    <setups>
      <setup id="generic">
        <!-- Configuration options: https://www.tiny.cloud/docs/tinymce/latest/initial-configuration/ -->
        <!-- Plugins: https://www.tiny.cloud/docs/plugins/#open-source-plugins -->
        <tinymceOptions>
          <![CDATA[
            {
              "menubar": true,
              "theme": "silver",
              "plugins": "preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help acecode",
...

See https://www.tiny.cloud/docs/plugins/#open-source-plugins for more information on the TinyMCE plugins.

To add TinyMCE buttons to the toolbar, add the names listed in the toolbar tag in the TinyMCE plugin documentation to toolbar(n) in the configuration.

Crafter Studio by default adds plugins to toolbar1 as seen in the example below.

...
"toolbar1": "formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat | editform",
...

See https://www.tiny.cloud/docs/tinymce/latest/toolbar-configuration-options/#toolbarn for more information on the toolbar(n) option of Tiny MCE

TinyMCE Plugin Toolbar Example

Let’s take a look at an example of using one of the TinyMCE plugins to add a button in the toolbar.

We’ll add a media button to our editor instance to be able to embed a YouTube video:

  1. Open the RTE configuration file in Studio by opening the Sidebar, then click on projectTools -> Configuration -> User Interface Configuration

  2. Add toolbar2 and the button name media like below:

    CRAFTER_HOME/data/repos/sites/SITENAME/sandbox/config/studio/ui.xml
    "toolbar1": "formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat",
    "toolbar2": "media",
    

    An Insert/Edit Embedded Media button rteMediaBtn will now be available for users of the RTE.

    RTE Setup - Media button added to editor instance

  1. Click on the rteMediaBtn button to add the link to the YouTube video you’d like to embed in the RTE and to setup other parameters. In the General tab, fill in the Source field with the URL of the YouTube video you’d like to embed and finally, fill in the Dimensions field to the size desired. Click on the Ok button.

    RTE Setup - Insert/Edit Embedded Media Example

  2. Save your changes, and your video should now be embedded in your page

    RTE Setup - YouTube video embedded in page, inserted through the RTE

TinyMCE Plugin Template Example

Let’s take a look at another example of using the TinyMCE plugin, template.

The template plugin adds support for custom templates. The default editor instance only adds the menu item Insert template... under the Insert menu in the menubar. On TinyMCE, it adds a menu item Insert template under the Insert menu and a toolbar button.

Note that the open-source template plugin and associated config options have been removed in TinyMCE 7. To achieve an equivalent TinyMCE config before the version 7 upgrade, the insert menu needs to be added/customised to the config as shown below:

"menu": {
  "tools": { "title": "Tools", "items": "tinymcespellchecker code acecode wordcount" },
  "insert": { "title": "Insert", "items": "image link media template codesample inserttable | charmap hr | pagebreak nonbreaking anchor | insertdatetime" }
},

To add a template to the RTE, simply add templates under setup in the RTE configuration. Under templates, add title, description and content

 1<widget id="craftercms.components.TinyMCE">
 2<configuration>
 3  <setups>
 4    <setup id="...">
 5       <tinymceOptions>
 6         <![CDATA[
 7           {
 8             "menubar": true,
 9             ...
10             "menu": {
11               "tools": { "title": "Tools", "items": "tinymcespellchecker code acecode wordcount" },
12               "insert": { "title": "Insert", "items": "image link media template codesample inserttable | charmap hr | pagebreak nonbreaking anchor | insertdatetime" }
13             },
14             "templates" : [
15               {
16                 "title": "Your Template Title",
17                 "content": "Your template content",
18                 "description": "Your Template Description "
19                },
20             ]
21          }
22     ]]>
23     ...

Let us take a look at an example of adding two templates to the RTE configuration

  1. Open the RTE configuration file in your project by opening the Sidebar, then click on projectTools -> Configuration -> User Interface Configuration

  2. Scroll down to the TinyMCE section and add in the following templates under <setup />:

    CRAFTER_HOME/data/repos/sites/SITENAME/sandbox/config/studio/ui.xml
     1"templates" : [
     2  {
     3    "title": "Test template 1",
     4    "content": "Test 1",
     5    "description": "Test1 Description "
     6  },
     7  {
     8    "title": "Test template 2",
     9    "content": "<div class='test'><h1>This is a title</h1><p>Look at this paragraph!</p></div>",
    10    "description": "Test 2 description"
    11  }
    12]
    

  3. Save your changes. The configured templates should now be available under Insert templates of the Insert menu.

    RTE Setup - RTE template plugin example in action

See https://www.tiny.cloud/docs/tinymce/6/template/ for more information on the template plugin.

TinyMCE paste plugin callback hooks

The TinyMCE paste plugin enables you to modify the pasted content before it gets inserted into the editor (paste_preprocess) and before it gets inserted into the editor but after it’s been parsed into a DOM structure (paste_postprocess). For more information on these options, see https://www.tiny.cloud/docs/tinymce/latest/copy-and-paste/#paste_preprocess.

In order to hook into the callback (paste_preprocess and paste_postprocess), do the following in the RTE configuration:

  1. Add the default paste plugin in plugins if not already included

    CRAFTER_HOME/data/repos/sites/SITENAME/sandbox/config/studio/ui.xml
    "plugins": "print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount textpattern help acecode paste"
    

  2. Create an external plugin by following the structure of the example plugin here. To modify the pasted content, add your code under paste_preprocess() or paste_postprocess() depending on your needs.

  3. Add the plugin created in the previous step as an external plugin under the craftercms_tinymce_hooks tag.

    CRAFTER_HOME/data/repos/sites/SITENAME/sandbox/config/studio/ui.xml
    "external_plugins": {
      "craftercms_tinymce_hooks": "/studio/1/plugin/file?siteId={site}&pluginId=craftercms&type=tinymce&name=craftercms_paste_extension&filename=samplepasteplugin.js"
    }
    

    For more information on craftercms_tinymce_hooks, see here

Note

When Tiny’s paste plugin is included, craftercms_paste_cleanup extension is also enabled. CrafterCMS’ extension performs some additional paste cleanup from what Tiny’s plugin does. To disable these additional processing of the paste input, you may add <craftercms_paste_cleanup>false</craftercms_paste_cleanup> to the RTE configuration

Adding Allowable Elements

Tiny MCE allows only a certain set of elements (HTML tags) as valid (rule set) by default in the code editor and will strip elements not in the allowable list when it outputs its HTML. For example, if you try adding in the <script /> element , or the <iframe /> element, it will be stripped out of the HTML output. To add specific elements that should also be valid, in addition to the existing rule set, we use the extended_valid_elements in the RTE configuration. Simply add the elements you would like added to the existing rule set in the <extended_valid_elements /> tag in RTE Configuration file.

"extended_valid_elements": "script mycustomtag",   <!-- elements whitelist (won't be stripped out) -->

Example allowing script element

Let’s take a look at an example of adding <script /> to the allowable elements (rule set). We’ll be using a project created using the Website Editorial blueprint.

  1. Open the RTE configuration file in Studio by opening the Sidebar, then click on projectTools -> Configuration -> User Interface Configuration then scroll down to the craftercms.components.TinyMCE widget section

  2. Scroll down to extended_valid_elements and add script and save.

    "extended_valid_elements": "script"   <!-- elements whitelist (won't be stripped out) -->
    

  3. We’ll now add <script /> in the RTE to verify it works.

    Open the Sidebar and edit one of the articles. Navigate to /articles/2020/7/ then right click on New ACME Phone Released Today and select Edit.

    Scroll down to the Content part of the form and Under Sections, click on Add Another

  4. Click on the newly added section, then click on Tools -> Code Editor from the RTE menubar.

    RTE Setup - Open RTE code editor

  5. Add a script in the code editor then save the changes. This will display a dialog saying Hello when you preview the article New ACME Phone Released Today

    <script>alert('Hello!')</script>
    

  6. Preview the page. A dialog saying Hello should pop up before the page is displayed

    RTE Setup - Preview page with <script /> added in RTE

    Please note that TinyMCE gives this warning when allowing script elements (<script />):

    Warning

    Allowing script elements (<script>) in TinyMCE exposes users to cross-site scripting (XSS) attacks.

Example allowing a custom element

You can also add custom elements to the rule set and can be done by simply adding the custom tag to extended_valid_elements. Let’s take a look at an example of adding the tag mycustomtag to the rule set.

Note

Case sensitive custom elements are not supported in TinyMCE 5. Remember to use only lowercase for custom elements (e.g. myattr is supported but myAttr is not supported).

  1. Open the RTE configuration file in Studio by opening the Sidebar, then click on projectTools -> Configuration -> User Interface Configuration then scroll down to the craftercms.components.TinyMCE widget section

  2. Scroll down to extended_valid_elements and add mycustomtag and save.

    "extended_valid_elements": [ "script", "mycustomtag"]
    

  3. We’ll now add the <mycustomtag /> in the RTE to verify it works.

    Open the Sidebar and edit one of the articles. Navigate to /articles/2020/7/ then right click on New ACME Phone Released Today and select Edit.

    Scroll down to the Content part of the form and Under Sections, click on one of the section, then click on Tools -> Code Editor from the RTE menubar, then use <mycustomtag />

    <mycustomtag>my custom tag</mycustomtag>
    

    RTE Setup - Open RTE code editor

Adding External Plugins

TinyMCE provides an option to specify URLS to plugins outside the tinymce plugins directory. These external plugins allow the user to extend TinyMCE. For example, you can create custom dialogs, buttons, menu items, etc.

For more information on the Tiny MCE external_plugins option, see https://www.tiny.cloud/docs/tinymce/latest/editor-important-options/#external_plugins

The Crafter Studio developer does not have full control of the tinymce initialization. To add a custom button to the toolbar in Crafter Studio, it would be done using the external plugin route since, what TinyMCE docs advise – i.e. using the setup function to add the button – is not viable in Studio without creating a form control plugin where they’d have full control of tinymce initialization.

To add an external plugin, use external_plugins in the RTE configuration. Use the Crafter Studio API that gets a file for a given plugin, the getPluginFile API found here getPluginFile to get the Tiny MCE external plugin file to pass to the RTE.

Example External Plugin

Let’s take a look at an example of a simple external plugin that creates a custom button which inserts text in the RTE. We’ll load our external plugin (a custom button) and add it to the RTE’s toolbar. For our example, we’ll be using a site created using the empty blueprint named hello.

  1. Open the RTE configuration file in Studio by opening the Sidebar, then click on projectTools -> Configuration -> User Interface Configuration then scroll down to the craftercms.components.TinyMCE widget section

  2. We’ll add the configuration for TinyMCE to load the plugin using Crafter Studio’s getPluginFile API. We achieve this by using external_plugins and adding child tags with the id of the plugin as tag name and the target URL as the tag’s content

    "external_plugins": {
      "my_button": "/studio/1/plugin/file?siteId={site}&pluginId=my_button&type=tinymce&name=my_button&filename=plugin.js"
    }
    

    where:

    {site}: a macro that inserts the current siteId

  3. Add the custom button we’re creating to the toolbar of the RTE. Scroll to the toolbar(n) tag and add the custom button we are creating my_button to toolbar2

    "toolbar2": "my_button"
    

  4. Finally, we’ll create our plugin file and add it in to Studio. See Plugins for more information on creating a Crafter Studio plugin.

    • Using information from step 2 for our external plugin, create the required directory structure for the plugin file, then create our plugin file named plugin.js

      $CRAFTER_HOME/data/repos/sites/SITE_NAME/sandbox/config/studio/plugins/tinymce/my_button/plugin.js
       1(function () {
       2
       3  'use strict';
       4
       5  tinymce.PluginManager.add("my_button", function (editor, url) {
       6
       7    function _onAction()
       8    {
       9      // Write something in the RTE when the plugin is triggered
      10      editor.insertContent("<p>Content added from my button.</p>")
      11    }
      12
      13    // Define the Toolbar button
      14    editor.ui.registry.addButton('my_button', {
      15        text: "My Button",
      16        onAction: _onAction
      17    });
      18  });
      19
      20  // Return details to be displayed in TinyMCE's "Help" plugin, if you use it
      21  // This is optional.
      22  return {
      23    getMetadata: function () {
      24      return {
      25        name: "My Button example",
      26        url: "http://exampleplugindocsurl.com"
      27      };
      28    }
      29  };
      30})();
      

      We recommend minimizing the plugin.js file. If your plugin is minimized, remember to change the external_plugins > my_button URL in the RTE configuration to load the minified version.

    • Remember to commit the new file so Studio will pick it up by doing a git add then a git commit. Whenever you edit directly in the filesystem, you need to commit your changes to ensure they are properly reflected.

  5. Let’s see the TinyMCE external plugin we created in action.

    Edit the Home page by opening the Sidebar then under Pages, right-click on Home, then select edit.
    Scroll down to the Main Content section of the form to view the RTE. Notice that the button we created is in the toolbar.

    RTE showing custom button

    Click on our custom button in the RTE My Button, and the line Content added from my button. will be inserted into the RTE

    RTE custom button clicked - text inserted in RTE

Adding support for valid child elements within a parent element

TinyMCE provides an option to control what child elements can exist within specified parent elements. By adding/removing child elements that can exist within a parent element, you can force which elements are valid children of the parent element.

To add/remove child elements to the list of valid child elements, add/remove the element in the valid_children tag in the RTE Configuration file. To add a child element to a parent element, use a + before the parent element then enclose in square brackets the child element/s you want to add e.g. +a[div|p]. To remove a child element, use a - before the parent element then enclose in square brackets the child element/s you want to remove, e.g. -a[img]. You can add multiple parent elements by using a comma separated list of parents with elements that should be added/removed as valid children

Example adding/removing elements for the specified parent
"valid_children" : "+body[style],-body[div],p[strong|a|#text]"

The example above shows you how to add style as a valid child of body and remove div as a valid child. It also forces only strong and a and text contents to be valid children of p.

For more information on the TinyMCE valid_children option, see https://www.tiny.cloud/docs/tinymce/latest/content-filtering/#valid_children

Example adding valid child elements to parent element

Let’s take a look at an example of how to add div and text content as valid children of a (html anchor) using the website editorial blueprint.

  1. Open the RTE configuration file in Studio by opening the Sidebar, then click on projectTools -> Configuration -> User Interface Configuration then scroll down to the craftercms.components.TinyMCE widget section

  2. Add valid_children and add div and text contents as child elements of a and save.

    RTE Configuration File
    "valid_children": "+a[div|#text]"
    

  3. We’ll now disable Force Root Block p Tag and Force p tags New Lines so that markup we enter in the RTE code editor will remain unchanged after saving your changes. Setting the Force Root Block p Tag option to false will never produce p tags on enter, or, automatically it will instead produce br elements and Shift+Enter will produce a p.

    Open the Article content type by opening the Sidebar, then click on projectTools -> Content Types -> Article -> Open Type. Scroll down to the Sections Repeating Group field, then click on the section_html field, which is an RTE.

    In the Properties Explorer on the right, remove the check mark on the property Force Root Block p Tag and Force p tags New Lines.

  4. We’ll now add markup in the RTE to test that div is now allowed to be a child element (nested) of parent element a.

    Open the Sidebar then click on Site Explorer and edit one of the articles. Navigate to /articles/2020/7/ then right click on New ACME Phone Released Today and select Edit.

    Scroll down to the Content part of the form and under Sections, click on Add Another.

    Click on the newly added section, then click on Tools -> Code Editor from the RTE menubar, then add the following:

    <a href="#">
      <div class="nesting_test_div">
        <img src="/static-assets/images/castle-pic.jpg" alt="" />
        <div class="nesting_test" title="Testing nesting elements">This is a test for nesting elements</div>
      </div>
    </a>
    

    After saving your changes, preview the page and it should now display an image and text that’s a link. Re-open the RTE code editor and verify that the markup you inputted is unchanged.

    RTE div child element added


Creating an RTE Setup

The RTE’s configuration file looks like this:

CRAFTER_HOME/data/repos/sites/SITENAME/sandbox/config/studio/ui.xml
 1<?xml version="1.0" encoding="UTF-8"?>
 2<siteUi>
 3  ...
 4  <widget id="craftercms.components.TinyMCE">
 5     <configuration>
 6       <setups>
 7         <setup id="generic">
 8           <!-- Configuration options: https://www.tiny.cloud/docs/tinymce/latest/initial-configuration/ -->
 9           <!-- Plugins: https://www.tiny.cloud/docs/tinymce/latest/plugins/#open-source-plugins -->
10           <tinymceOptions>
11             <![CDATA[
12               {
13                 "menubar": true,
14                 "theme": "silver",
15                 "plugins": "print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount textpattern help acecode paste",
16                 "extended_valid_elements": "",
17                 "valid_children": "",
18                 "toolbar1": "formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat",
19                 "code_editor_wrap": false,
20                 "toolbar_sticky": true,
21                 "image_advtab": true,
22                 "encoding": "xml",
23                 "relative_urls": false,
24                 "remove_script_host": false,
25                 "convert_urls": false,
26                 "remove_trailing_brs": false,
27                 "media_live_embeds": true,
28                 "autoresize_on_init": false,
29                 "autoresize_bottom_margin": 0,
30                 "menu": {
31                   "tools": { "title": "Tools", "items": "tinymcespellchecker code acecode wordcount" },
32                   "insert": { "title": "Insert", "items": "image link media template codesample inserttable | charmap hr | pagebreak nonbreaking anchor | insertdatetime" }
33                   },
34                   "automatic_uploads": true,
35                   "file_picker_types":  "image media file",
36                   "paste_data_images": true,
37                   "templates": [],
38                   "content_css": [],
39                   "content_style": "body {}",
40                   "contextmenu": false
41                 }
42               ]]>
43             </tinymceOptions>
44           </setup>
45         </setups>
46       </configuration>
47     </widget>
48     ...

You can access the RTE Configuration file by going to the Sidebar then clicking on projectTools. In the Project Tools, click on Configuration, then from the list, select User Interface Configuration. Scroll down to the craftercms.components.TinyMCE widget section.

RTE Setup - Open RTE Configuration File in Studio

Inside the <setups> tag, there can be multiple <setup> tags. Each setup represents a possible RTE configuration that can be specified to be used by a RTE control. To add your own configuration, create a new <setup> tag. Each <setup> tag contains:


Attaching an RTE in a Form to an RTE Setup

To attach an RTE setup to an RTE in a form, open the content type that you want to add an RTE to, then go to the Properties Explorer and click on RTE Configuration and type in an RTE setup name.

RTE Setup - Add an RTE in the Form

In the image above, the RTE setup name used is generic. Please see the section above on how to create an RTE Setup, where the example shows an RTE Setup named generic.


Extending TinyMCE

CrafterCMS provides a general tool for extending TinyMCE via the craftercms_tinymce_hooks. It currently allows for hooking into the following (as shown by the example here):

  • paste_preprocess callback

  • paste_postprocess callback

  • setup function

To hook into the paste pre/post process of TinyMCE, see here.