Advanced RTE Configurations

In ExpressionEngine 7.2, Rich Text Editor fields can now be configured using JSON and custom CSS or JS files. This allows site admins more control over how the field and its content look and what editors are allowed to do. It also allows quicker configuration of these fields over the drag and drop toolbar interface if you have a standard toolset you use on most of your sites.

Custom CSS

In our first example, we want to allow content editors to format text as headers but only use H2 and H3 tags. We also want the headers to look just like on the frontend of the site (in our example that will be blue text-color and underlined).

Create The CSS Template

First, we will create a CSS template for the styles that we need. We do this by creating a new template in the Template Editor and selecting “CSS” as the type.

In our template, we will add some simple CSS. Again, our goal is to have H2 and H3 headers appear blue and underlined simply. For this example, we’ll use the following snippet:

h2,h3 {
    color: #36c;
    text-decoration: underline;
}

Configure RTE

Now that we have our custom stylesheet, we will edit the toolset configuration used by our RTE field and select the CSS template with our styles.

To do this, select the RTE configuration you would like to edit by navigating to the Rich Text Editor add-on, then selecting the configuration you want to edit from the “Available Tool Sets” section.

Next, we will select our stylesheet under “Custom Stylesheet” and toggle on “Advanced configuration.” Activating the advanced configuration will reveal the “Configuration JSON” field, which is being pre-populated with JSON config based on the currently saved configuration.

We will edit it by removing the options that we don’t need and end up with the following:

{
    "toolbar": {
        "items": [
            "heading",
            "bold",
            "italic",
            "underline"
        ]
    },
    "heading": {
        "options": [
            {
                "model": "paragraph",
                "title": "Paragraph"
            },
            {
                "model": "heading2",
                "view": "h2",
                "title": "Header",
                "class": "ck-heading_heading2"
            },
            {
                "model": "heading3",
                "view": "h3",
                "title": "Subheader",
                "class": "ck-heading_heading3"
            }
        ]
    }
}

The settings will only allow content editors to use the heading, bold, italic, and underline tools. The heading options will only be paragraph, Header (which will be an H2 using our custom styles), and Subheader (which will be an H3 using our custom styles).

Then Save the updated configuration.

Learn more about editing CKEditor configurations

CKEditor Docs

Learn more about editing Redactor configurations

Redactor Docs

Using Your Configuration

Now that your custom styles and toolset are saved, content editors will only see the available options with their respective styles when editing your field in an entry.

Custom JavaScript

It is also possible to add custom JavaScript to Redactor. This is particularly useful when adding custom plugins to Redactor. For this example, we’re going to add a button to our Redactor toolbar, which will prompt the user for text and then add a danger alert box when clicked.

Using custom JS with CKEditor is a little more complicated so we will not cover that here. Be sure to check out the ExpressionEngine docs if you need to add custom JS to CKEditor.

Create the JS Template

Start by creating a new template in the Template Editor and selecting “JavaScript” as the type.

In our template, we will slightly modify the “Sample plugin with modal window” demo plugin from Imperavi.

(function($R)
{
    $R.add('plugin', 'warningAlert', {
        modals: {
            'warningAlert': '<form action="">'
                + '<div class="form-item">'
                    + '<label>## warningAlert-label ##</label>'
                    + '<textarea name="text" style="height: 200px;"></textarea>'
                + '</div>'
            + '</form>'
        },
        translations: {
            en: {
                "warningAlert": "Add A Warning",
                "warningAlert-label": "Please, type some text"
            }
        },
        init: function(app)
        {
            // define app
            this.app = app;

            // define services
            this.lang = app.lang;
            this.toolbar = app.toolbar;
            this.insertion = app.insertion;
        },

        // messages
        onmodal: {
            warningAlert: {
                opened: function($modal, $form)
                {
                    $form.getField('text').focus();
                },
                insert: function($modal, $form)
                {
                    var data = $form.getData();
                    this._insert(data);
                }
            }
        },

        // public
        start: function()
        {
            // create the button data
            var buttonData = {
                title: this.lang.get('warningAlert'),
                api: 'plugin.warningAlert.open'
            };

            // create the button
            var $button = this.toolbar.addButton('warningAlert', buttonData);
        },
        open: function()
        {
            var options = {
                title: this.lang.get('warningAlert'),
                width: '600px',
                name: 'warningAlert',
                handle: 'insert',
                commands: {
                    insert: { title: this.lang.get('insert') },
                    cancel: { title: this.lang.get('cancel') }
                }
            };

            this.app.api('module.modal.build', options);
        },

        // private
        _insert: function(data)
        {
            this.app.api('module.modal.close');

            if (data.text.trim() === '') return;

            this.insertion.insertHtml('<div class="alert"><span class="closebtn" onclick="this.parentElement.style.display=\'none\'\;">&times;</span><strong>Danger!</strong> '+ data.text +'</div>');
        }
    });
})(Redactor);

This plugin will create a button on our field with the label of “Add A Warning”. When the user clicks the button, a modal appears with a textarea for the user to input the text to be displayed in the warning alert box. Once submitted the text wrapped in our HTML and inserted into the field using Redactor’s insertHtml() service.

Learn more about creating Redactor plugins

Redactor Developer Docs

Note that we have also added these custom styles to our RTE stylesheet using the steps in the first half of this article. To follow along, the styles for this alert box are:

.alert {
  padding: 20px;
  background-color: #f44336;
  color: white;
}

.closebtn {
  margin-left: 15px;
  color: white;
  font-weight: bold;
  float: right;
  font-size: 22px;
  line-height: 20px;
  cursor: pointer;
  transition: 0.3s;
}

.closebtn:hover {
  color: black;
}

Configure RTE

Now that we have our JS template, we can configure our RTE toolset.

To do this, select the RTE configuration you would like to edit by navigating to the Rich Text Editor add-on, then selecting the configuration you want to edit from the “Available Tool Sets” section. Again, be sure to choose a toolset based on Redactor for our example.

Next, we will toggle on “Advanced configuration.” Activating the advanced configuration will reveal the “Configuration JSON” field, which is being pre-populated with JSON config based on the currently saved configuration as well as the “Extra Javascript” dropdown.

In the Configuration JSON field, we will add our plugin to the list of plugins (from the sample code we used we know our plugin is labeled warningAlert):

{
    "buttons": [
        "bold",
        "italic",
        "underline",
        "ol",
        "ul",
        "link"
    ],
    "plugins": [
        "warningAlert"
    ]
}

Now in the Extra JavaScript field, we will select our JavaScript template created above.

Using Your Configuration

Now that your custom configuration and plugin are saved, our button is available when editing your field in an entry.

Comments 0

Be the first to comment!