CKEditor Plugins
CKEditor supports a wide range of plugins that extend its core functionality. Each plugin is identified by a unique, lowercase name, which you reference in the CKEditor configuration.
Table of Contents
- Available plugins
- Add an existing CKEditor plugin
- Remove an existing CKEditor plugin
- Add a custom CKEditor plugin
- CKEditor plugin that opens a Wicket dialog
Available Plugins
Bloomreach Content includes the following CKEditor plugins by default:
| Plugin | Description | Used by default in Formatted Text Fields in | Used by default in Rich Text Fields in | Available since release | ||
|---|---|---|---|---|---|---|
| Content | Channels | Content | Channels | |||
| a11yhelp | Accessibility Help | No | No | Yes | Yes | 10.0 |
| about | About CKEditor | No | No | No | No | 10.0 |
| autogrow | Auto Grow | No | Yes [2] | No | Yes [2] | 12.0 |
| autolink | Auto Link | No | No | Yes | Yes | 13.1 |
| balloonpanel | Balloon Panel | No | No | No | No | 12.0 |
| balloontoolbar | Balloon Toolbar | No | No | No | No | 12.5 |
| basicstyles | Basic Styles | Yes | Yes | Yes | Yes | 10.0 |
| bidi | BiDi (Text Direction) | No | No | No | No | 10.0 |
| blockquote | Blockquote | No | No | No | No | 10.0 |
| button | UI Button | Yes | Yes | Yes | Yes | 10.0 |
| clipboard | Clipboard | Yes | Yes | Yes | Yes | 10.0 |
| codemirror | CodeMirror (Source) Syntax Highlighting | No | No | Yes | Yes | 10.0 |
| codesnippet | Code Snippet | No | No | No | No | 10.0 |
| colorbutton | Color Button | No | No | No | No | 10.0 |
| colordialog | Color Dialog | No | No | No | No | 10.0 |
| copyformatting | Copy Formatting | Yes | Yes | Yes | Yes | 12.0 |
| contextmenu | Context Menu | Yes | Yes | Yes | Yes | 10.0 |
| dialog | Dialog | Yes | Yes | Yes | Yes | 10.0 |
| dialogadvtab | Advanced Tab for Dialogs | No | No | Yes | Yes | 10.0 |
| dialogui | Dialog User Interface | Yes | Yes | Yes | Yes | 10.0 |
| div | Div Container Manager | No | No | No | No | 10.0 |
| divarea | Div Editing Area | Yes | Yes | Yes | Yes | 10.0 |
| elementspath | Elements Path | No | No | Yes | Yes | 10.0 |
| emoji | Emoji | No | No | No | No | 13.1 |
| enterkey | Enter Key | Yes | Yes | Yes | Yes | 10.0 |
| entities | Escape HTML Entities | Yes | Yes | Yes | Yes | 10.0 |
| fakeobjects | Fake Objects | No | No | No | No | 10.0 |
| filebrowser | File Browser | No | No | No | No | 10.0 |
| find | Find / Replace | No | No | No | No | 10.0 |
| floatingspace | Floating Space | Yes | Yes | Yes | Yes | 10.0 |
| floatpanel | Floating Panel | Yes | Yes | Yes | Yes | 10.0 |
| font | Font Size and Family | No | No | No | No | 10.0 |
| format | Format | No | No | No | No | 10.0 |
| forms [1] | Form Elements | No | No | No | No | 10.0 |
| hippoautosave | Bloomreach Content auto save | Yes | Yes | Yes | Yes | 10.0 |
| hippopicker | Bloomreach Content pickers for images and internal links | No | No | Yes | Yes | 10.0 |
| horizontalrule | Horizontal Rule | No | No | No | No | 10.0 |
| htmlwriter | HTML Output Writer | Yes | Yes | Yes | Yes | 10.0 |
| iframe | IFrame Dialog | No | No | No | No | 10.0 |
| iframedialog | Iframe Dialog Field | No | No | No | No | 13.4 |
| image | Image | No | No | No | No | 10.0 |
| image2 | Enhanced Image | No | No | No | No | 10.0 |
| indent | Indent / Outdent | No | No | Yes | Yes | 10.0 |
| indentblock | Indent Block | No | No | Yes | Yes | 10.0 |
| indentlist | Indent List | No | No | Yes | Yes | 10.0 |
| justify | Justify | No | No | Yes | Yes | 10.0 |
| language | Language | No | No | No | No | 10.0 |
| link | Link | No | No | Yes | Yes | 10.0 |
| list | List | No | No | Yes | Yes | 10.0 |
| listblock | List Block | Yes | Yes | Yes | Yes | 10.0 |
| liststyle | List Style | No | No | Yes | Yes | 10.0 |
| magicline | Magic Line | Yes | Yes | Yes | Yes | 10.0 |
| mathjax | Mathematical Formulas | No | No | No | No | 10.0 |
| maximize | Maximize | No | No [3] | Yes | No [3] | 10.0 |
| mentions | Mentions | No | No | No | No | 13.1 |
| menu | Menu | Yes | Yes | Yes | Yes | 10.0 |
| menubutton | Menu Button | Yes | Yes | Yes | Yes | 10.0 |
| notification | Notification | No | No | No | No | 10.2 |
| pagebreak | Page Break | No | No | No | No | 10.0 |
| panel | Panel | Yes | Yes | Yes | Yes | 10.0 |
| panelbutton | Panel Button | Yes | Yes | Yes | Yes | 10.0 |
| pastefromword | Paste from Word | No | No | Yes | Yes | 10.0 |
| pastetext | Paste as Plain Text | No | No | Yes | Yes | 10.0 |
| placeholder | Placeholder | No | No | No | No | 10.0 |
| popup | Popup | No | No | Yes | Yes | 10.0 |
| removeformat | Remove Format | Yes | Yes | Yes | Yes | 10.0 |
| resize | Editor Resize | No | No [3] | Yes | No [3] | 10.0 |
| richcombo | Rich Combo | Yes | Yes | Yes | Yes | 10.0 |
| selectall | Select All | No | No | No | No | 10.0 |
| sharedspace | Shared Space | No | Yes [2] | No | Yes [2] | 12.0 |
| showblocks | Show Blocks | No | No | Yes | Yes | 10.0 |
| showborders | Show Table Borders | No | No | Yes | Yes | 10.0 |
| smiley | Insert Smiley | No | No | No | No | 10.0 |
| sourcearea | Source Editing Area | No | No [3] | No | No [3] | 10.0 |
| sourcedialog | Source Dialog | No | Yes [2] | No | Yes [2] | 12.0 |
| specialchar | Special Characters | No | No | Yes | Yes | 10.0 |
| stylescombo | Styles Combo | Yes | Yes | Yes | Yes | 10.0 |
| tab | Tab Key Handling | Yes | Yes | Yes | Yes | 10.0 |
| table | Table | No | No | Yes | Yes | 10.0 |
| tableresize | Table Resize | No | No | Yes | Yes | 10.0 |
| tableselection | Table Selection | No | No | Yes | Yes | 12.0 |
| tabletools | Table Tools | No | No | Yes | Yes | 10.0 |
| templates | Content Templates | No | No | No | No | 10.0 |
| textselection | Keep TextSelection | No | No | Yes | Yes | 10.0 |
| toolbar | Editor Toolbar | Yes | Yes | Yes | Yes | 10.0 |
| undo | Undo | Yes | Yes | Yes | Yes | 10.0 |
| widget | Widget | No | No | No | No | 10.0 |
| wordcount | Word Count and Character Count | No | No | No | No | 10.0 |
| wysiwygarea | IFrame Editing Area | No | No | No | No | 10.0 |
| youtube | YouTube Plugin | No | No | Yes | Yes | 10.0 |
- The 'forms' plugin requires CKEditor to run in an
iframeinstead of adiv. Refer to the example configuration for setup instructions. - Explicitly enabled by the system.
- Explicitly disabled by the system.
Info:
All plugins are available in both Content and Channels, except for a few that are explicitly disabled in Channels:
- The maximize plugin is replaced by the "full width toggle" in the right side-panel.
- The sourcearea plugin is not compatible with the inline version of CKEditor, so Channels uses the sourcedialog plugin instead.
- The resize plugin does not work with the inline version of CKEditor, so Channels uses the autogrow plugin instead.
Runtime Debugging
You can retrieve the list of available plugins at runtime:
- Log in to Bloomreach Content using Chrome or Firefox.
- Edit a document type that includes an HTML field.
- Open Chrome DevTools or Firebug.
- Run the following JavaScript to list all registered plugins:
Object.keys(CKEDITOR.plugins.registered).sort()
To inspect the plugins used by a specific editor instance:
- Print the map of all CKEditor instances to identify the editor instance name:
CKEDITOR.instances - List all plugins for a specific instance (for example, 'editor123'):
Object.keys(CKEDITOR.instances.editor123.plugins).sort()
Add an Existing CKEditor Plugin
To enable a CKEditor plugin already included in Bloomreach Content, set the [extraPlugins](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-extraPlugins) configuration property. For example, to add the 'About' plugin:
ckeditor.config.overlayed.json:
{
extraPlugins: 'about'
}
Some plugins add buttons to toolbar groups that are not shown by default. In this case, also add the relevant toolbar group. For example, to display the 'About' button in rich text fields, add the following configuration:
ckeditor.config.appended.json:
{
toolbarGroups: [
{ name: 'about' }
]
}
Remove an Existing CKEditor Plugin
To disable a CKEditor plugin that is enabled by default, use the [removePlugins](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removePlugins) configuration property. For example, to remove the 'stylescombo' plugin:
ckeditor.config.overlayed.json:
{
removePlugins: 'stylescombo'
}
Add a Custom CKEditor Plugin
You can package custom CKEditor plugins in any .jar file included with the 'cms' application in your project. The recommended approach is to add them directly to the 'cms' artifact.
Place the source code for custom CKEditor plugins under:
src/main/resources/ckeditor/plugins/
Create a subdirectory for each plugin, using the plugin name as the directory name. Each plugin must include a main plugin.js file, and may include additional files or icons as needed.
In production, the CMS loads an optimized version of CKEditor sources from src/main/resources/ckeditor/optimized. You should also provide an optimized version of your custom plugin in this directory. For small custom plugins, copying the source files using the Maven resources plugin is sufficient (see the example below).
Info:
In Wicket development mode, the CMS loads the plain CKEditor and plugin sources. In Wicket production mode, it loads the optimized sources. Develop custom plugins in Wicket development mode and use a tool like JRebel to hot-deploy your changes.
Info:
Starting with brXM 11, you must explicitly include CKEditor sources when building your project. Set the system propertyinclude.ckeditor.sources:mvn clean verify -Dinclude.ckeditor.sourcesThis approach reduces the size of production WAR files by excluding unused CKEditor sources.
Hint:
For guidance on developing CKEditor plugins, see the CKEditor plugin SDK documentation. If your plugin adds HTML elements, update the HTML cleaning configuration to support them. Review the advanced content filter integration and update the server-side HTML cleaner configuration as needed.
Example: Timestamp Plugin
The CKEditor developer's guide provides an example plugin called 'timestamp'. To add this plugin to a project created from the archetype, follow these steps:
-
Download the source code and copy the tutorial-timestamp/timestamp directory into
cms/src/main/resources/ckeditor/plugins. The resulting structure should be:cms/ src/ main/ resources/ ckeditor/ plugins/ timestamp/ icons/ timestamp.png plugin.js -
To provide an optimized copy of the sources, add the following to the
build/pluginssection ofcms/pom.xml:<build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>create-optimized-resources</id> <phase>generate-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/classes/ckeditor/optimized</outputDirectory> <resources> <resource> <directory>${basedir}/src/main/resources/ckeditor</directory> </resource> </resources> </configuration> </execution> </executions> </plugin> ... </plugins> </build> -
Build and start the project:
mvn clean verify mvn -Pcargo.run -
Log in to the CMS as 'admin' and edit the 'newsdocument' type in the document type editor (Documents > Configuration > myproject > newsdocument > Edit).
-
Select the 'Body' field and add the 'timestamp' plugin to the overlayed CKEditor configuration:
ckeditor.config.overlayed.json:
{ extraPlugins: 'timestamp' }
The 'timestamp' icon should now appear in the toolbar for the 'Body' field editor.
For more information about creating CKEditor plugins, see the Simple CKEditor Plugin Tutorial.
CKEditor Plugin That Opens a Wicket Dialog
You can create a custom CKEditor plugin that opens a Wicket dialog in Bloomreach Content. This requires:
- A CKEditor plugin for client-side logic and UI.
- A custom
CKEditorNodePluginJava class that creates aCKEditorPanelwith an additionalCKEditorPanelExtension.
The 'hippopicker' plugin is an example. It adds 'image' and 'internal link' buttons that open Bloomreach Content pickers (Wicket dialogs). Each CKEditor field is rendered by the CKEditorPanel class. The default CKEditorNodePlugin adds the server-side Wicket behavior for the hippopicker plugin to the CKEditorPanel. To add your own server-side behavior, extend CKEditorNodePlugin. First, add the following dependency to your CMS pom.xml (or to another artifact included in the CMS WAR):
<dependency> <groupId>org.onehippo.cms7</groupId> <artifactId>hippo-cms-richtext-ckeditor-frontend</artifactId> </dependency>
Override the createEditPanel method in your custom plugin class and add a CKEditorPanelExtension:
public class MyCKEditorNodePlugin extends CKEditorNodePlugin { @Override protected CKEditorPanel createEditPanel(String id, String editorConfigJson) { CKEditorPanel panel = super.createEditPanel(id, editorConfigJson); panel.addExtension(new MyCKEditorPanelExtension(...)); return panel; } }
Implement MyCKEditorPanelExtension to add Wicket behaviors for your picker and provide the Ajax URL to the editorConfig JSON object. The client-side plugin can use this URL to open the server-side picker. The server-side can render JavaScript to invoke a CKEditor command when the picker closes.
To use your custom plugin class, update the plugin class property:
/hippo:namespaces/hippostd/html/editor:templates/_default_/root
- plugin.class = org.example.MyCKEditorNodePlugin
Visual Editor
Plugins that open Wicket dialogs cannot be used in HTML fields in the Visual Editor. Ensure your plugin only initializes when the editor is loaded in a Wicket context:
CKEDITOR.plugins.add('mywicketbasedplugin', { init: function (editor) { if (window.Wicket) { // initialize plugin } } }
Alternatively, avoid using Wicket. For example, implement your plugin using CKEditor UI widgets and call a custom REST API by creating a repository JAX-RS service.