Documentation / How To

Create a plugin

Quick start #

Create a JS file, write the plugin code in it and connect it after the JS file of the editor.

Here is a generic example of a plugin template:


Redactor.add('plugin', 'myplugin', {
    // call when the editor initialize all modules & plugins (optional method)
    init:() {
         // define local variables
         this.myvariable = true;
    },

    // call when the editor starts (optional method)
    start() {
        if (this.myvariable) {
            this.myMethod();
            this._myPrivateMethod();
        }
    },

    // call when the editor stops (optional method)
    stop() {
        this.myvariable = false;
    },

    // public methods
    myMethod() {
        // do something
    },

    // private
    _myPrivateMethod() {
        // do something
    }
});

And now we run the plugin at the start of Redactor.


Redactor('#entry', {
    plugins: ['myplugin']
});

Methods #

init

The plugin may have an optional init method. This method is started by the editor when initializing the classes of all modules and plugins. I.e. before the editor starts.

In this method, we usually declare the plugin's local variables for the plugin work.

start

The plugin may have an optional start method. This method starts after the initialization of all modules and plugins.

In this method, we usually build all the initial business logic of the plugin.

stop

The plugin may have an optional stop method. This method is called when the editor is stopped.

Usually in this method we build stop plugin actions, for example, stopping Dom events, deleting elements created by the plugin, etc.

public

Public methods are called outside the plugin, for example, they handle the commands of the plugin buttons or are called by the API by other plugins.

private

Private methods are called inside the plugin and are the main tool for building the plugin.

API #

Inside any plugin, the object this.app is available with which you can access any module of the editor.

Here is an example of accessing the Toolbar module to create a button:

Redactor.add('plugin', 'myplugin', {
    start() {
        this.app.toolbar.add('mybutton', {
            title: 'My Button',
            icon: '<svg...>',
            command: 'myplugin.toggle'
        });
    },
    toggle(args) {
        // do something
    }
});

Access to another plugin's method is similar to accessing module methods using this.app.


Redactor.add('plugin', 'myplugin', {
    start() {
        this.app.mysecondplugin.toggle();
    }
});

See more how the API works.

Event #

Plugins can subscribe to editor events with the subscribe object.


Redactor.add('plugin', 'myplugin', {
    subscribe: {
        'block.remove': function(event) {
            this.catchBlockRemove(event);
        }
    },
    start() {
        // myplugin start actions
    },
    catchBlockRemove(event) {
        // do something
    }
});

In this example, the catchBlockRemove plugin method will be called each time a block is deleted in the editor.

Any plugin can create its own events using the this.app.broadcast method. These events as well as the editor events can be caught in another plugin.

Here is an example of creating an event in a plugin when it starts:


Redactor.add('plugin', 'myplugin', {
    start() {
        this.app.broadcast('myplugin.start');
    }
});

And this is how you can caught this event in another plugin:


Redactor.add('plugin', 'mysecondplugin', {
    subscribe: {
        'myplugin.start': function() {
            this.catchMypluginStart();
        }
    },
    catchMypluginStart:() {
        // do something
    }
});

See more how events work.

Settings #

Plugin settings can be specified in the defaults object. In this case, the editor will automatically include them into a single object of all settings. This means that these settings can be changed at the start of the editor, and access them using this.opts inside the plugin.

Here is an example of specifying the defaults object.


Redactor.add('plugin', 'myplugin', {
    defaults: {
        myvariable: true
    },
    start() {
        if (this.opts.is('myplugin.myvariable')) {
            let value = this.opts.get('myplugin.myvariable');
            this.myMethod();
        }
    },
    myMethod() {
        // do something
    }
});

And this is how you can change the settings of the plugin at the start of the editor:


Redactor('#entry', {
    plugins: ['myplugin']
    myplugin: {
        myvariable: false
    }
});

Translations #

The easiest way to translate a plugin is to add language variables directly to its code, using the translations object.

For example:


Redactor.add('plugin', 'myplugin', {
    translations: {
        en: {
            "myplugin": {
                "get-code": "Get Code",
                "set-code": "Set Code"
            }
        },
        de: {
            "myplugin": {
                "get-code": "Code abrufen",
                "set-code": "Code einstellen"
            }
        }
    },
    start() {
        // get the language variable
        let value = this.lang.get('myplugin.get-code');

        // parse a string with language variable
        let str = this.lang.parse('My string with ## myplugin.get-code ## variable.');
    }
});

In the same example, in the start method, you can see how to access the language variables in the plugin and how to convert the variable if it is in a text string.

You can see how to specify language variables in the plugin, using the example of the Inline Format plugin.

Shortcuts #

You can assign a keyboard shortcut to the plugin method. To do this, use the API method add of the Shortcuts module.


Redactor.add('plugin', 'myplugin', {
    start() {
        this.app.hotkeys.add('ctrl+j, meta+j', {
            title: 'Toggle my plugin',
            name: 'meta+j',
            command: 'myplugin.toggle'
        });
    },
    toggle() {
        console.log('Shortcut action');
    }
});

Examples #