Please contact IBM if you require support.
Customization Steps
Please refer to the following IBM Knowledge Center article:
https://www.ibm.com/support/knowledgecenter/SSYJ99_8.5.0/wcm/wcm_config_ephox_custom.html
Examples
Info:
For more information regarding the customization of Textbox.io, please see:
Caution:
Many items in the default configuration have WCM specific values. Altering these values may have a detrimental impact on your editing experience.
Ephox advises that changes only be made to the following items:
- paste
- ui
isSpellCheckingEnabled
isImageProxyEnabled
isLinkValidationEnabled
isMediaEmbedEnabled
isToneEnabled
The sample configuration provided by IBM contains the following base configuration object:
... var config = { css: { stylesheets: styleSheetUrl ? [styleSheetUrl] : [] }, images: { editing: { proxy: isImageProxyEnabled ? urlImageProxyService : undefined }, allowLocal: !isLimitedToLibraryImagePicker }, ui: { locale: locale, toolbar: { items: items } }, codeview: { enabled: isCodeViewEnabled }, spelling: { url: isSpellCheckingEnabled ? urlSpellingService : undefined }, links: { validation: { url: isLinkValidationEnabled ? urlLinkService : undefined }, embed: { url: isMediaEmbedEnabled ? urlLinkService : undefined } }, cognitive: { tone: { url: isToneEnabled ? urlToneService : undefined } }, textboxioExtensions: [ ] }; ...
This base object will be used in the examples.
Once the customizations have been applied, the configuration must be installed as per IBM's documentation.
Enabling/Disabling Service Functionality
Textbox.io makes use of various server-side services to provide spell checking, proxying of images for editing, validation of links, generating media embeds from links, and tone analysis.
These features can be enabled/disabled in the configuration using the following true/false values, which are defined directly above the config object:
// Disable/Enable services var isSpellCheckingEnabled = true; var isImageProxyEnabled = true; var isLinkValidationEnabled = false; var isMediaEmbedEnabled = false; var isToneEnabled = false;
To enable a feature set the value to true, to disable set the value to false.
Note that changing the value to true/false only enables/disabled the service; it does not turn the actual service on/off.
By default the spell checking and image proxy are enabled but the link validation, media embedding and tone analysis need to be enabled. This is because the link validation, media embedding and tone analysis will need additional configuration of the Ephox services to allow access to websites using SSL and to work correctly with proxy servers. Additionally the tone analysis service will need an IBM Watson tone analysis service key.
Modifying Paste Functionality
Textbox.io provides multiple different ways to handle the pasting of content, which can be changed modifying the value of the "paste" configuration property. The different behaviors are explained here: http://docs.ephox.com/display/tbio/paste
The default value for the "paste" configuration is "retain". If plain-text pasting is preferred you need to add the "paste" configuration property and set the value to "plain". Like this:
, paste: { style: 'plain' }
So the following configuration would be specified:
... var config = { css: { stylesheets: styleSheetUrl ? [styleSheetUrl] : [] }, images: { editing: { proxy: isImageProxyEnabled ? urlImageProxyService : undefined }, allowLocal: !isLimitedToLibraryImagePicker }, ui: { locale: locale, toolbar: { items: items } }, codeview: { enabled: isCodeViewEnabled }, spelling: { url: isSpellCheckingEnabled ? urlSpellingService : undefined }, links: { validation: { url: isLinkValidationEnabled ? urlLinkService : undefined }, embed: { url: isMediaEmbedEnabled ? urlLinkService : undefined } }, cognitive: { tone: { url: isToneEnabled ? urlToneService : undefined } }, textboxioExtensions: [ ], paste: { style: 'plain' } }; ...
Adding Additional Buttons
Adding buttons to the editor provides a convenient way of exposing new functionality to users.
The IBM sample configuration contains a helper function for building buttons. It has the following signature:
button(id, tooltipText, iconPath, action);
The action parameter is a function with the following signature:
function(wcmEditorId) { // do action here }
The wcmEditorId
can be used to access Textbox.io and modify its contents.
Example snippets
Refer to the API reference for full details but here are a few examples.
Get editor content
Get the body of the editor document as HTML.
var content = ephox.wcm.api.getEditor(wcmEditorId).getBody();
Get selected text
Get the currently selected text. All HTML tags will be removed from the returned value.
var selectedText = ephox.wcm.api.getEditor(wcmEditorId).getSelection().getText();
Get selected HTML
Get the currently selected HTML. Partially selected tags are automatically closed at the selection boundaries.
var selectedHtml = ephox.wcm.api.getEditor(wcmEditorId).getSelection().getHtml()
Replace editor content
Completely replace the body of the editor document with the new HTML.
Side effects
- This will clear the current selection.
- This will clear the undo list.
ephox.wcm.api.getEditor(wcmEditorId).setBody(content);
Replace selection
Overwrite the current selection with the HTML snippet or insert it at the current cursor position if no selection has been made.
Side effects
- This will clear the current selection.
ephox.wcm.api.getEditor(wcmEditorId).insertHtmlAtCursor(htmlSnippet);
Get text direction
Query the text direction.
var dir = ephox.wcm.api.getEditor(wcmEditorId).getDirection();
Basic Example
The following example:
- Creates a new button
- Creates a new button group containing the new button
- Adds the new button group to the default toolbar.
... // Create a new button using the helper function. var newButton = button("newButton", "New button tooltip", "<path-to-an icon>", function(wcmEditorId) {alert("Click!");}); // Create a new button group var newGroup = { label: "New Button Group", items: [newButton] }; // Append the new button to the existing array of toolbar items. items.push(newGroup); var config = { css: { stylesheets: styleSheetUrl ? [styleSheetUrl] : [] }, images: { editing: { proxy: isImageProxyEnabled ? urlImageProxyService : undefined }, allowLocal: !isLimitedToLibraryImagePicker }, ui: { locale: locale, toolbar: { items: items } }, codeview: { enabled: isCodeViewEnabled }, spelling: { url: isSpellCheckingEnabled ? urlSpellingService : undefined }, links: { validation: { url: isLinkValidationEnabled ? urlLinkService : undefined }, embed: { url: isMediaEmbedEnabled ? urlLinkService : undefined } }, cognitive: { tone: { url: isToneEnabled ? urlToneService : undefined } }, textboxioExtensions: [ ] }; ...
Advanced Example
The following example:
- Creates two buttons.
- Creates a new item group.
- Adds the new group to the toolbar.
- Shows how you might change the document with buttons
... // ROT13 encode some English alphabet text leaving all other characters untouched var rot13Text = function(text) { var out = ''; var char_a = 'a'.charCodeAt(0); var char_z = 'z'.charCodeAt(0); var char_A = 'A'.charCodeAt(0); var char_Z = 'Z'.charCodeAt(0); for (var i = 0; i < text.length; i++) { var char = text.charCodeAt(i); var outChar; if (char >= char_a && char <= char_z) { out += String.fromCharCode((((char - char_a) + 13) % 26) + char_a); } else if (char >= char_A && char <= char_Z) { out += String.fromCharCode((((char - char_A) + 13) % 26) + char_A); } else { out += text.charAt(i); } } return out; }; // ROT13 encode the text nodes in some HTML, leaving the HTML untouched var rot13Html = function(html) { var container = document.createElement('div'); container.innerHTML = html; // depth first traversal var node = container.firstChild; while (node !== null && node !== container) { // check for a text node if (node.nodeType === 3) { node.nodeValue = rot13Text(node.nodeValue); } // transition to next node in depth first traversal if (node.firstChild) { node = node.firstChild; } else if (node.nextSibling) { node = node.nextSibling; } else { // find the first parent that has a sibling and transition to it node = node.parentNode; while (node !== null && node !== container && node.nextSibling === null) { node = node.parentNode; } if (node !== null && node !== container) { node = node.nextSibling; } } } return container.innerHTML; }; // ROT13 encode the entire editor contents // Side effects: // - Will clear the undos // - Will loose selection var rot13Body = function(wcmEditorId) { var editor = ephox.wcm.api.getEditor(wcmEditorId); editor.setBody(rot13Html(editor.getBody())); }; // ROT13 encode the currently selected text // Side effects: // - Will loose selection var rot13Selection = function(wcmEditorId) { var editor = ephox.wcm.api.getEditor(wcmEditorId); var selection = editor.getSelection(); editor.insertHtmlAtCursor(rot13Html(selection.getHtml())); }; // Create 2 new buttons using the helper function. var encryptDocumentButton = button("encryptDocument", "Encrypt the entire document", "<path-to-an icon>", rot13Body); var encryptSelectionButton = button("encryptSelection", "Encrypt the current selection", "<path-to-an icon>", rot13Selection); // Create a group to hold the buttons var encryptionButtonGroup = { label: 'Encryption', items: [encryptDocumentButton, encryptSelectionButton] }; // Append the new group to the existing array of toolbar items. items.push(encryptionButtonGroup); var config = { css: { stylesheets: styleSheetUrl ? [styleSheetUrl] : [] }, images: { editing: { proxy: isImageProxyEnabled ? urlImageProxyService : undefined }, allowLocal: !isLimitedToLibraryImagePicker }, ui: { locale: locale, toolbar: { items: items } }, codeview: { enabled: isCodeViewEnabled }, spelling: { url: isSpellCheckingEnabled ? urlSpellingService : undefined }, links: { validation: { url: isLinkValidationEnabled ? urlLinkService : undefined }, embed: { url: isMediaEmbedEnabled ? urlLinkService : undefined } }, cognitive: { tone: { url: isToneEnabled ? urlToneService : undefined } }, textboxioExtensions: [ ] }; ...
Modifying Existing Editor Configurations
It may be desirable to remove functionality from the editor in certain situations.
The following example:
- Creates a new toolbar configuration without the "Insert" button group.
- Adds the new configuration to the toolbar.
... // This is the default definition for the toolbar items in the sample config var items = flatten([ ['undo', insertGroup, 'style', 'emphasis', 'align', 'listindent'], styleGroup('format'), [languageGroup, toolsGroup] ]); // Creating a new array of items, filtering out the one var newItems = items.filter(function(item) {return item !== insertGroup}); var config = { css: { stylesheets: styleSheetUrl ? [styleSheetUrl] : [] }, images: { editing: { proxy: isImageProxyEnabled ? urlImageProxyService : undefined }, allowLocal: !isLimitedToLibraryImagePicker }, ui: { locale: locale, toolbar: { items: items } }, codeview: { enabled: isCodeViewEnabled }, spelling: { url: isSpellCheckingEnabled ? urlSpellingService : undefined }, links: { validation: { url: isLinkValidationEnabled ? urlLinkService : undefined }, embed: { url: isMediaEmbedEnabled ? urlLinkService : undefined } }, cognitive: { tone: { url: isToneEnabled ? urlToneService : undefined } }, textboxioExtensions: [ ] }; ...
Attachments:
Configure.png (image/png)
Preferences.png (image/png)
Start application.png (image/png)
Select TextboxioForWCM.png (image/png)
WebSphere enterprise applications.png (image/png)
Installing.png (image/png)
Summary.png (image/png)
Map virtual hosts.png (image/png)
Map modules to server.png (image/png)
Installation options.png (image/png)
Fast Path.png (image/png)
Choose File.png (image/png)
New Enterprise Application.png (image/png)
New Application.png (image/png)