Concrete5 uses CKEditor as its WYSIWYG editor. It is powerful, it offers plenty of free and paid plugins and it generates decent markup. One thing that’s missing though is an easy way to customize editors’ toolbars independently. Concrete5 only lets you customize CKEditor sitewide. I’m going to show you how to easily customize specific editors.

Setting up CKEditor sitewide

Setting up CKEditor sitewide is as simple as it gets.

Very simply, navigate to your dashboard’s Editor page /dashboard/system/basics/editor. Alternatively, type “editor” in your intelligent search box in the top toolbar and you’ll get there.

Once on the Editor’s page, you’ll see a list of all your plugins alongside checkboxes.

Check and uncheck those boxes as needed and save.

That’s it, you have just set up CKEditor to your liking sitewide.

Now let’s see how to break free of sitewide settings and customize specific instances of the editor.

The very simple way to customize specific editors

This is a simple 4 steps process:

  1. Grab an instance of the editor’s object
  2. Select only the plugins you want and deselect the rest
  3. Output the editor
  4. Reset the plugins to the way they were for the next editor

See, nothing to it…

This process is the same whether you want to use it in a block or on a dashboard page. Almost anywhere you are outputting the CKEditor you can do this.

I said “almost” because there is a caveat. This will not work when you output the editor inline so it won’t work with the content block for instance. And let me be totally honest I have no idea why and it is doing my head in. But as soon as I figure it out I’ll make sure to post a solution.

On the other hand, it works exceptionally well with the standard editor so it works with Express Forms for instance, or in dashboard pages.

Show me the code

The code is simple to follow.

// Before we do anything we have to decide which plugins we want to enable
// We need to know their handles which we'll talk about later
$allowedPlugins = ['handle1', 'handle2', 'handle3'];

// We need an instance of the Application container so let's grab that
$app = \Concrete\Core\Support\Facade\Application::getFacadeApplication();

// Then we need an instance of the editor's object
$editor = $app->make('editor');

// If this is going to be public facing
// maybe disable access to the file manager and the sitemap
$editor->setAllowFileManager(false);
$editor->setAllowSitemap(false);
        
// Then we need and instance of the Editor's plugin manager'
$pluginManager = $editor->getPluginManager();

// We grab a list of all the currently selected plugins
$selectedPlugins = $pluginManager->getSelectedPlugins();

// We deselect them
$pluginManager->deselect($selectedPlugins);

// Some plugins are hidden but required by concrete5
// Let's grab them and select them
$config = $app->make('site')->getDefault()->getConfigRepository();
$corePlugins = $config->get('editor.ckeditor4.plugins.selected_hidden');
$pluginManager->select($corePlugins);

// The we select our chosen plugins
$pluginManager->select($allowedPlugins);

// We output our standard editor and we give it a handle
// $editorValue contains the content to be displayed in the editor if any
echo $editor->outputStandardEditor('editor_handle', $editorValue);

// These last 2 steps are only necessary if you have other editors on the page
// which should have a different configuration than the current editor.
// we deselect the plugins we just selected
$pluginManager->deselect($allowedPlugins);

// And we reselect the plugins that were originally selected
$pluginManager->select($selectedPlugins);

Finding our plugins’ handles

Go back to your dashboard’s Editor page /dashboard/system/basics/editor and have a look at each checkbox. The value of each checkbox is the handle of the corresponding plugin.

For instance, the checkbox for the plugin “Accessibility Help” looks like this:

<input type="checkbox" id="plugin_a11yhelp" name="plugin[]" class="ccm-input-checkbox" value="a11yhelp">

The value “a11yhelp” is the handle for this particular plugin.

Once you have all your plugins’ handles modify the code above to list them. For instance:

$allowedPlugins = [
    'wysiwygarea',
    'basicstyles',
    'list',
    'undo',
    'toolbar',
    'pastetext',
    'clipboard',
];

Here’s a demo of the editor with only the plugins listed in the code above:

Please wait while the editor is loading…

And here’s another one with the standard configuration. This one is able to use the standard configuration because I reselected all the plugins after outputting the first editor:

Please wait while the editor is loading…

Using this code with a concrete5 Express Form

Let’s use an Express Form (block’s name: “Form”) as an example to try our code.

First, make a copy of the block’s concrete\blocks\express_form\view.php file and create a template that you will apply to the form you want to customize.

Let’s say you want to name your template “Express Form Editor Light”. Put your copy of the View file in application\blocks\express_form\templates\express_form_editor_light\view.php.

Around line 15 of the form’s View we have this:

<?php if (isset($renderer)) {
?>

This is where you will add the code that comes before the editor is generated.

Then lower down, around line 38, we have this line of code: $renderer->render();

That’s where the whole form is generated, including any editor you added to your form. So right after that line, you can add the rest of our code. Remember you don’t need to generate the editor yourself since it is generated by the renderer above.

Here’s the whole code for your template:

<?php defined('C5_EXECUTE') or die('Access Denied.');

/* @var \Concrete\Core\Block\View\BlockView $view */
/* @var \Concrete\Core\Express\Form\Renderer|null $renderer */
/* @var string|null $success */
/* @var string $bID */
/* @var \Concrete\Core\Error\ErrorList\ErrorList|null $error */
/* @var \Concrete\Core\Captcha\CaptchaInterface|null $captcha */
/* @var string $displayCaptcha "0" or "1" */
/* @var string $submitLabel */
?>
<div class="ccm-block-express-form">
    <?php // We have a renderer so we know the form will be generated
    // So we can start working on our editor's customization
    if (isset($renderer)) {
        // Before we do anything we have to decide which plugins we want to enable
        $allowedPlugins = [
            'wysiwygarea',
            'basicstyles',
            'list',
            'undo',
            'toolbar',
            'pastetext',
            'clipboard',
        ];

        // We need an instance of the Application container so let's grab that
        $app = \Concrete\Core\Support\Facade\Application::getFacadeApplication();

        // Then we need an instance of the editor's object
        $editor = $app->make('editor');
        
        // If this is going to be public facing
        // maybe disable access to the file manager and the sitemap
        $editor->setAllowFileManager(false);
        $editor->setAllowSitemap(false);

        // Then we need and instance of the Editor's plugin manager
        $pluginManager = $editor->getPluginManager();

        // We grab a list of all the currently selected plugins
        $selectedPlugins = $pluginManager->getSelectedPlugins();

        // We deselect them
        $pluginManager->deselect($selectedPlugins);
        
        // Some plugins are hidden but required by concrete5
        // Let's grab them and select them
        $config = $app->make('site')->getDefault()->getConfigRepository();
        $corePlugins = $config->get('editor.ckeditor4.plugins.selected_hidden');
        $pluginManager->select($corePlugins);

        // The we select our plugins
        $pluginManager->select($allowedPlugins);

    ?>
        <div class="ccm-form">
            <a name="form<?=%24bID;%20?>"></a>

            <?php if (isset($success)) {
        ?>
                <div class="alert alert-success">
                    =$success; ?>
                </div>
            <?php } ?>

            <?php if (isset($error) && is_object($error)) {
        ?>
                <div class="alert alert-danger">
                    =$error->output(); ?>
                </div>
            <?php } ?>

            <form enctype="multipart/form-data" class="form-stacked" method="post" action="<?=%24view->action('submit');%20?>#form<?=%24bID;%20?>">
                <?php // This line renders the form including the editor if any
                // So let's reset our plugin selection right after
                $renderer->render();

                // we deselect the plugins we just selected
                $pluginManager->deselect($allowedPlugins);

                // And we reselect the plugins that were originally selected
                $pluginManager->select($selectedPlugins);

    if ($displayCaptcha) {
        ?>
                    <div class="form-group captcha">
                        <?php $captchaLabel = $captcha->label();
        if (!empty($captchaLabel)) {
            ?>
                            <label class="control-label"><?php echo $captchaLabel; ?></label>
                            <?php } ?>

                        <div><?php $captcha->display(); ?></div>
                        <div><?php $captcha->showInput(); ?></div>
                    </div>
                <?php } ?>

                <div class="form-actions">
                    <button type="submit" name="Submit" class="btn btn-primary">=t($submitLabel); ?></button>
                </div>
            </form>
        </div>
    <?php } else {
        ?>
        <p>=t('This form is unavailable.'); ?></p>
    <?php } ?>
</div>

Now add an Express Form to your page, make sure it includes a field of type “Text Area” with an input format of “Rich Text”.

Apply the template you just created and you’ll instantly see your customized toolbar.

This is great if you want to let users send you messages with styling (Bold, Italic, Lists… ) but not too many options (Images, Links, Tables… )

Where to go from here

Beware, shameless plug ahead 🙈 I can only highly recommend 😏 my own **cough** paid **cough** package “Plugin Installer for CKEditor” that allows you to install third-party plugins you download from CKEditor’s marketplace.

Feel free to visit the plugin’s demo page and market page to find out more about it.

And the cherry on top is it does work with inline editors as well—using a different more complex way than this article presents—so you can customize the content block.​​

It might also be an excellent idea to read “Adding CKEditor custom editor styles in a theme” by community member extraordinaire MrKDilkington.

Get your free consultation

Got a project that could use specialised eyes on? Tell me more about it and let's discuss how to get that ball rolling.

Share the details →

Get emergency help

Every single day your website acts up, you lose income opportunities. I can get your site back to normal right away.

Get help now →