Rich Editor / WYSIWYG Field
Form Widget
richeditor - renders a visual editor for rich formatted text, also known as a WYSIWYG editor.
html_content:
type: richeditor
label: Contents
The following field properties are supported and commonly used.
| Property | Description |
|---|---|
| label | a name when displaying the form field to the user. |
| default | specifies a default string value, optional. |
| comment | places a descriptive comment below the field. |
| toolbar | reference a named toolbar definition by its code. Example: shop-content |
| toolbarButtons | buttons to show on the editor toolbar. Example: bold|italic |
| size | specifies a field size for fields that use it, for example, the textarea field. Options: tiny, small, large, huge, giant. |
| showMargins | set to true to include resizable document margins. Default: false. |
| useLineBreaks | uses line breaks instead of paragraph wrappers for each new line. Default false. |
| editorOptions | custom editor options used by the editor control as an array (advanced). |
You may specify how large the field size should be with the size property.
html_content:
type: richeditor
label: Contents
size: huge
Use the toolbarButtons property to specify custom buttons.
html_content:
type: richeditor
label: Contents
toolbarButtons: bold|italic|underline
The double-pipe || character can be used to include a separator with the buttons.
toolbarButtons: bold|italic|underline||insertPageLink||undo|redo||clearFormatting
The available toolbar buttons are:
- fullscreen
- bold
- italic
- underline
- strikeThrough
- subscript
- superscript
- fontFamily
- fontSize
- color
- emoticons
- inlineStyle
- paragraphStyle
- paragraphFormat
- align
- formatOL
- formatUL
- outdent
- indent
- quote
- insertHR
- insertLink
- insertPageLink
- insertImage
- insertVideo
- insertAudio
- insertFile
- insertTable
- insertSnippet
- undo
- redo
- clearFormatting
- selectAll
- html
The | character will insert a vertical separator line in the toolbar.
# Toolbar Definitions
Toolbar definitions are named button configurations that can be shared by many rich editor fields and managed visually in the Settings → Editor Settings → Toolbar Buttons area. Each definition has a unique code, a label and a description explaining where it is used. Definitions are edited with a visual builder by dragging buttons between the toolbar and the available buttons palette.
The following definitions are included by default.
| Code | Description |
|---|---|
| default | used by rich editors without a specific toolbar. |
| minimal | a compact toolbar for simple content. |
| full | every available button. |
Use the toolbar property to reference a definition from a rich editor field. The same code can be shared by any number of fields, and updating the definition updates every field that references it.
description:
type: richeditor
toolbar: shop-content
A definition with no buttons inherits the default toolbar. This makes it possible to give an area of the admin panel its own toolbar code without prescribing any buttons, the fields simply follow the default toolbar until the definition is customized. The visual builder displays the inherited buttons for empty definitions, and modifying them makes the definition independent from the default toolbar. Definitions that have been changed from their registered configuration display as modified, along with a Reset to Default option to restore them.
Administrators may also create their own definitions with new codes using the Create Toolbar button, which can then be referenced from form fields and blueprints in the same way.
# Registering a Toolbar Definition
Plugins register toolbar definitions using the registerRichEditorToolbars method of the plugin registration file. Each definition supplies a label and a description, along with an optional button list.
public function registerRichEditorToolbars()
{
return [
'shop-content' => [
'label' => 'Shop Content',
'description' => 'Used by shop product and category descriptions.',
],
];
}
The definition above contains no buttons, so it inherits the default toolbar until an administrator customizes it. Specify the buttons value as a comma separated list to register an opinionated button set, which also acts as the baseline for the Reset to Default feature.
public function registerRichEditorToolbars()
{
return [
'shop-content' => [
'label' => 'Shop Content',
'description' => 'Used by shop product and category descriptions.',
'buttons' => 'paragraphFormat, bold, italic, |, insertImage, insertPageLink, html',
],
];
}
Registered definitions appear in the settings area automatically, where administrators can review and customize them. Custom buttons registered in JavaScript can be included in a definition by their registered name.
# Toolbar Precedence
The toolbar button list is resolved for each editor from the first available source.
- The field
toolbarButtonsproperty, used exactly as written. - The field
toolbarproperty, resolved to its toolbar definition. - The default toolbar definition, when it has been customized.
- The built-in default button list.
Custom buttons registered with a toolbar placement (see below) are added to the default toolbar automatically, and the default definition in the settings area displays them in place. Modifying the default toolbar stores the visible buttons exactly, making the placed buttons real entries that can be moved or removed. Every other source is used verbatim, so include the custom button name in the toolbar definition to display it there.
# Registering a Custom Button
Custom toolbar buttons are registered in JavaScript using the oc.richEditor.registerButton function. The API is available on every backend page, even when no rich editor is present, and the definition is editor-agnostic, it is not coupled to the underlying editor engine.
oc.richEditor.registerButton('insertCustomThing', {
label: 'Insert Something',
icon: 'icon-star',
toolbar: 'end',
undo: true,
focus: true,
onClick: function(editor) {
editor.insertHtml('<strong>My Custom Thing!</strong>');
}
});
Register the JavaScript globally on every backend page, so the button is available to every rich editor surface, including the form widget and the CMS editor.
Event::listen('backend.page.beforeDisplay', function($controller) {
$controller->addJs('/plugins/october/test/assets/js/custom-button.js');
});
Call registerButton at the top level of your script, plain and module scripts both work. Do not wrap the call in oc.pageReady(). Registration must complete before the first editor on the page initializes, which is guaranteed for any script included in the page.
The following properties are supported by the button definition.
| Property | Description |
|---|---|
| label | the button tooltip and accessible label. |
| icon | an icon class name, for example icon-star, or custom markup as { html: '<svg>...</svg>' }. |
| toolbar | where to place the button: start, end, { before: 'name' } or { after: 'name' }. Omit to register the command without placing it. |
| separator | inserts a separator line next to the button: before, after or both. |
| undo | records an undo step after the button action. Default: true. |
| focus | focuses the editor before the button action. Default: true. |
| onClick | function called when the button is clicked, receives the editor instance. |
# The Editor Instance
The onClick function receives an editor object with the following methods, which remain stable across editor engine versions.
| Method | Description |
|---|---|
| insertHtml(html) | inserts HTML at the cursor position. |
| insertElement(element) | inserts a DOM element or jQuery object. |
| insertUiBlock(node) | inserts a non-editable block element. |
| getContent() / setContent(html) | reads or replaces the document contents. |
| saveSelection() / restoreSelection() | preserves the selection around popups or dialogs. |
| focus() | focuses the editing surface. |
| saveUndoStep() | records an undo checkpoint. |
| engine | the active engine name, for advanced use. |
| native | the raw engine instance, engine-specific and subject to change. |
# Trigger a Modal from a Custom Button
Use the oc.popup JavaScript function to open a modal window.
oc.popup({
handler: 'onLoadPopup'
});
Use the backend.ajax.beforeRunHandler to register a global AJAX handler. The makePartial method can be called to render a partial with the modal contents inside.
Event::listen('backend.ajax.beforeRunHandler', function ($controller, $handler) {
if ($handler === 'onLoadPopup') {
return $controller->makePartial('~/path/to/my/partials/_popup_form.php');
}
});
# Advanced Editor Options
Use the editorOptions property to customize the editor options. This is an advanced property, since all options defined here are proxied directly to the editor control.
html_content:
type: richeditor
editorOptions:
imageDefaultWidth: 0
The options are proxied to the underlying Froala editor. The most commonly used options are listed below, grouped by area.
# Image Options
| Option | Description |
|---|---|
| imageUpload | Enables image uploads. Set to false to block users from inserting images via the upload button or by dropping image files into the editor. Default: true. |
| imagePaste | Allows pasting images from the clipboard. Set to false to strip pasted images. Default: true. |
| imagePasteProcess | When true, pasted images are re-uploaded through the configured upload handler instead of being kept as inline data. Default: false. |
| imageMove | Allows existing images inside the editor to be dragged to a new position. Set to false to lock images in place. Default: true. |
| imageResize | Allows images to be resized by dragging their corners. Set to false to disable resizing. Default: true. |
| imageResizeWithPercent | When true, image sizes are stored as percentages rather than fixed pixel widths. Default: false. |
| imageRoundPercent | When true, percentage-based image sizes are rounded to whole numbers. Default: false. |
| imageDefaultWidth | Sets the default width of an image when it is inserted. Setting it to 0 will not set any width. Default: 300. |
| imageDefaultAlign | Sets the default image alignment when inserted. Possible values are left, center and right. Default: center. |
| imageDefaultDisplay | Sets the default display for an inserted image. Possible values are inline and block. Default: block. |
| imageDefaultMargin | Default margin in pixels applied to inserted images. Default: 5. |
| imageMinWidth | Minimum width (in pixels) when resizing an image. Default: 16. |
| imageMaxSize | Maximum allowed upload size in bytes. Default: 10485760 (10MB). |
| imageAllowedTypes | Array of allowed image file extensions for uploads. Default: ['jpeg', 'jpg', 'png', 'gif', 'webp']. |
| imageMultipleStyles | When false, only one style class can be applied to an image at a time. Default: true. |
| imageTextNear | Allows text to wrap next to an inserted image. Default: true. |
| imageOutputSize | When true, image width and height attributes are written into the output HTML. Default: false. |
| imageSplitHTML | When true, the editor will split paragraphs to place block images. Default: false. |
| imageAddNewLine | When true, a new line is automatically added after an inserted image. Default: false. |
| imageStyles | Object mapping CSS class names to style labels available in the image edit popup. Default includes fr-rounded, fr-bordered, fr-shadow. |
# File Upload Options
| Option | Description |
|---|---|
| fileUpload | Enables file uploads. Set to false to disable. Default: true. |
| fileMaxSize | Maximum allowed file upload size in bytes. Default: 10485760 (10MB). |
| fileAllowedTypes | Array of allowed MIME subtypes for uploads, or ['*'] for any. Default: ['*']. |
# Drag and Drop
| Option | Description |
|---|---|
| dragInline | When true, dragged content is dropped at the cursor position inline. When false, drag-and-drop inside the editor is disabled. Default: true. |
# Where to find the full list
The editorOptions values are passed through to the underlying Froala v2 editor. Every available option, along with its default, is declared at the top of each plugin file under vendor_drm/froala/js/plugins/ in the October CMS source — for example image.js for image options and file.js for file upload options.
# Example: block all image insertion
html_content:
type: richeditor
editorOptions:
imageUpload: false
imagePaste: false
imageMove: false