Create a plugin for OpenTiny
OpenTiny is designed to be easily extended by custom plugins; with APIs for registering custom plugins, and creating and localizing custom UI.
Requirements
To be recognized as a plugin by OpenTiny, the code for a custom plugin must have a JavaScript file with a single entry point that registers the plugin with OpenTiny using the PluginManager
API. Any other code or resources can be in separate files and can be loaded in any standard manner. OpenTiny also has various APIs for loading scripts and stylesheets.
OpenTiny does not require any special file structure or tooling apart from these requirements, so custom plugins can be developed using most frameworks and tools.
Yeoman Generator
Tiny maintains a Yeoman generator to assist with creating plugins for OpenTiny. The Yeoman Generator will create the files and boilerplate code required for a custom plugin, and sets up some helpful commands.
Registering a custom plugin with OpenTiny
Register a custom plugin with OpenTiny using the PluginManager. PluginManager.add()
takes a string for the plugin identifier and a function that contains the code for initializing the plugin.
The plugin identifier passed to PluginManager.add()
is used by OpenTiny as an identifier string. It should:
-
Be an alphanumeric string,
-
Not contain any spaces or other whitespaces,
-
Be a unique identifier that does not match the IDs of plugins provided with OpenTiny or any other OpenTiny plugin in use.
If multiple plugins have the same identifier, one will override the others.
Optionally, the function passed to PluginManager.add()
can return an object that contains data that OpenTiny or other plugins can use. Tiny recommends including a getMetadata
callback that returns an object containing data that can be used to populate the list of plugins in the Help plugin dialog. The metadata object should contain the following values:
-
name
: A string that contains the plugin’s name, usually in a human-readable format. -
url
: A string that contains a URL, usually used to link to help documentation.
Using custom plugins with OpenTiny
Custom plugins can be added to a OpenTiny instance by either:
-
Using
external_plugins
: Use theexternal_plugins
option to specify the URL-based location of the entry point file for the plugin. -
Copy code into
plugins
folder: Copy the entry point file (and any other files) into theplugins
folder of the distributed OpenTiny code. The plugin can then be used by including it in the list of plugins specified by theplugins
option.
Tiny recommends using the external_plugins option for custom plugins.
|
Testing OpenTiny
Due to the range of browser APIs used by OpenTiny; when testing OpenTiny or any custom plugins, OpenTiny requires a testing framework that runs on a real browser. Testing frameworks that mock the browser will not work.
Language localization
If a custom plugin includes any custom UI created using OpenTiny’s UI APIs, then it may require localization.
OpenTiny comes with translations for many strings in many languages. To add additional strings to a supported language for a custom plugin, use the following procedure.
-
Create a “langs” directory in the custom plugin’s root directory for custom translations.
-
For each language that the plugin supports, create a translation file.
The files should be JavaScript files and use the relevant language code as the file name. For example: OpenTiny will search for a Spanish translation file at
<your plugin>/langs/es_ES.js
, where<your plugin>
is to the directory that contains the plugin’s entry point file. For a list of supported languages, see: Supported languages. -
In each translation file, add translation strings by passing an object containing key-value pairs of source strings and translation strings to the
tinymce.addI18n()
API. -
In the plugin’s entry point file, call
tinymce.PluginManager.requireLangPack()
and pass it the plugin identifier and a comma-delimitated string of the language codes to load.
Example plugin
This example plugin demonstrates how to add a simple toolbar button and menu item. This button opens a dialog that allows a title to be entered into the editor. The menu item will open the same dialog as the button.
-
TinyMCE
-
HTML
-
JS
-
Edit on CodePen
<textarea id="custom-plugin"><p>To add a `Title: ` to the editor content, click "My button" and fill the dialog, then save the change.</p><p> </p></textarea>
/*
Note: We have included the plugin in the same JavaScript file as the OpenTiny
instance for display purposes only. Tiny recommends not maintaining the plugin
with the OpenTiny instance and using the `external_plugins` option.
*/
tinymce.PluginManager.add('example', (editor, url) => {
const openDialog = () => editor.windowManager.open({
title: 'Example plugin',
body: {
type: 'panel',
items: [
{
type: 'input',
name: 'title',
label: 'Title'
}
]
},
buttons: [
{
type: 'cancel',
text: 'Close'
},
{
type: 'submit',
text: 'Save',
buttonType: 'primary'
}
],
onSubmit: (api) => {
const data = api.getData();
/* Insert content when the window form is submitted */
editor.insertContent('Title: ' + data.title);
api.close();
}
});
/* Add a button that opens a window */
editor.ui.registry.addButton('example', {
text: 'My button',
onAction: () => {
/* Open window */
openDialog();
}
});
/* Adds a menu item, which can then be included in any menu via the menu/menubar configuration */
editor.ui.registry.addMenuItem('example', {
text: 'Example plugin',
onAction: () => {
/* Open window */
openDialog();
}
});
/* Return the metadata for the help plugin */
return {
getMetadata: () => ({
name: 'Example plugin',
url: 'http://exampleplugindocsurl.com'
})
};
});
/*
The following is an example of how to use the new plugin and the new
toolbar button.
*/
tinymce.init({
selector: 'textarea#custom-plugin',
plugins: 'example help',
toolbar: 'example | help'
});