craftcms/ckeditor

Edit rich text content in Craft CMS using CKEditor.

Installs: 123 189

Dependents: 15

Suggesters: 0

Security: 0

Stars: 41

Watchers: 9

Forks: 20

Open Issues: 20

Type:craft-plugin

4.0.3 2024-03-28 19:55 UTC

README

CKEditor icon

CKEditor

This plugin adds a “CKEditor” field type to Craft CMS, which provides a deeply-integrated rich text and longform content editor, powered by CKEditor 5.

A CKEditor field with example content filled in.

Table of Contents:

Requirements

This plugin requires Craft CMS 5.0.0-beta.7 or later.

Installation

You can install this plugin from the Plugin Store or with Composer.

From the Plugin Store:

Go to the Plugin Store in your project’s Control Panel and search for “CKEditor”. Then click on the “Install” button in its modal window.

With Composer:

Open your terminal and run the following commands:

# go to the project directory
cd /path/to/my-project.test

# tell Composer to load the plugin
composer require craftcms/ckeditor

# tell Craft to install the plugin
./craft plugin/install ckeditor

Configuration

CKEditor configs are managed globally from SettingsCKEditor.

Configurations define the available toolbar buttons, as well as any custom config options and CSS styles that should be regisered with the field.

New configs can also be created inline from CKEditor field settings.

A “Create a new field” page within the Craft CMS control panel, with “CKEditor” as the chosen field type. A slideout is open with CKEditor config settings.

Registering Custom Styles

CKEditor’s Styles plugin makes it easy to apply custom styles to your content via CSS classes.

You can define custom styles within CKEditor configs using the style config option:

return {
  style: {
    definitions: [
      {
        name: 'Tip',
        element: 'p',
        classes: ['note']
      },
      {
        name: 'Warning',
        element: 'p',
        classes: ['note', 'note--warning']
      },
    ]
  }
}

You can then register custom CSS styles that should be applied within the editor when those styles are selected:

.ck.ck-content p.note {
    border-left: 4px solid #4a7cf6;
    padding-left: 1rem;
    color: #4a7cf6;
}

.ck.ck-content p.note--warning {
    border-left-color: #e5422b;
    color: #e5422b;
}

HTML Purifier Configs

CKEditor fields use HTML Purifier to ensure that no malicious code makes it into its field values, to prevent XSS attacks and other vulnerabilities.

You can create custom HTML Purifier configs that will be available to your CKEditor fields. They should be created as JSON files in your config/htmlpurifier/ folder.

Use this as a starting point, which is the default config that CKEditor fields use if no custom HTML Purifier config is selected:

{
  "Attr.AllowedFrameTargets": [
    "_blank"
  ],
  "Attr.EnableID": true
}

See the HTML Purifier documentation for a list of available config options.

For advanced customization, you can modify the HTMLPurifier_Config object directly via the craft\ckeditor\Field::EVENT_MODIFY_PURIFIER_CONFIG event.

use craft\htmlfield\events\ModifyPurifierConfigEvent;
use craft\ckeditor\Field;
use HTMLPurifier_Config;
use yii\base\Event;

Event::on(
    Field::class,
    Field::EVENT_MODIFY_PURIFIER_CONFIG,
    function(ModifyPurifierConfigEvent $event) {
        /** @var HTMLPurifier_Config $config */
        $config = $event->config;
        // ...
    }
);

Embedding Media

CKEditor 5 stores references to embedded media embeds using oembed tags. Craft CMS configures HTML Purifier to support these tags, however you will need to ensure that the URI.SafeIframeRegexp HTML Purifier setting is set to allow any domains you wish to embed content from.

See CKEditor’s media embed documentation for examples of how to show the embedded media on your front end.

Longform Content with Nested Entries

CKEditor fields can be configured to manage nested entries, which will be displayed as cards within your rich text content, and edited via slideouts.

A CKEditor field with a nested entry’s slideout open.

Nested entries can be created anywhere within your content, and they can be moved, copied, and deleted, just like images and embedded media.

Setup

To configure a CKEditor field to manage nested entries, follow these steps:

  1. Go to SettingsFields and click on your CKEditor field’s name (or create a new one).
  2. Double-click on the selected CKEditor config to open its settings.
  3. Drag the “New entry” menu button into the toolbar, and save the CKEditor config.
  4. Back on the field’s settings, select one or more entry types which should be available within CKEditor fields.
  5. Save the field’s settings.

Now the field is set up to manage nested entries! The next time you edit an element with that CKEditor field, the “New entry” menu button will be shown in the toolbar, and when you choose an entry type from it, a slideout will open where you can enter content for the nested entry.

An entry card will appear within the rich text content after you press Save within the slideout. The card can be moved via drag-n-drop or cut/paste from there.

You can also copy/paste the card to duplicate the nested entry.

To delete the nested entry, simply select it and press the Delete key.

Note

Copy/pasting entry cards across separate CKEditor fields is not supported.

Rendering Nested Entries on the Front End

On the front end, nested entries will be rendered automatically via their partial templates.

For each entry type selected by your CKEditor field, create a _partials/entry/<entryTypeHandle>.twig file within your templates/ folder, and place your template code for the entry type within it.

An entry variable will be available to the template, which references the entry being rendered.

Tip

If your nested entries contain any relation fields, you can eager-load their related elements for each of the CKEditor field’s nested entries using eagerly().

{% for image in entry.myAssetsField.eagerly().all() %}

Converting Redactor Fields

You can used the ckeditor/convert command to convert any existing Redactor fields over to CKEditor. For each unique Redactor config, a new CKEditor config will be created.

php craft ckeditor/convert

Adding CKEditor Plugins

Craft CMS plugins can register additional CKEditor plugins to extend its functionality.

The first step is to create a DLL-compatible package which provides the CKEditor plugin(s) you wish to add.

💡 Check out CKEditor’s Implementing an inline widget tutorial for an in-depth look at how to create a custom CKEditor plugin.

Once the CKEditor package is in place in your Craft plugin, create an asset bundle which extends BaseCkeditorPackageAsset. The asset bundle defines the package’s build directory, filename, a list of CKEditor plugin names provided by the package, and any toolbar items that should be made available via the plugin.

For example, here’s an asset bundle which defines a “Tokens” plugin:

<?php

namespace mynamespace\web\assets\tokens;

use craft\ckeditor\web\assets\BaseCkeditorPackageAsset;

class TokensAsset extends BaseCkeditorPackageAsset
{
    public $sourcePath = __DIR__ . '/build';

    public $js = [
        'tokens.js',
    ];

    public array $pluginNames = [
        'Tokens',
    ];

    public array $toolbarItems = [
        'tokens',
    ];
}

Finally, ensure your asset bundle is registered whenever the core CKEditor asset bundle is. Add the following code to your plugin’s init() method:

\craft\ckeditor\Plugin::registerCkeditorPackage(TokensAsset::class);