TinyMCE 4 – Adding custom toolbar icons to a plugin

If you’re poking around the standard TinyMCE 4 plugins to see how to configure a toolbar icon you might be left scratching your head a little. Fortunately it’s a lot easier than it may first appear

When tasked with creating a new custom plugin for TinyMCE many of us poke through the standard plugins that ship with the editor to work out how to do it. If the plugin you want to write needs a toolbar icon you might be a little confused about how to do it with TinyMCE 4, since none of the plugin folders include one.

If you’ve had a look at how the other toolbar buttons are configured in your browser’s DOM explorer you’ll know that the icons for all the standard plugin buttons are provided in a TrueType font file (tinymce.ttf) which is part of the theme’s skin:-

 

A TinyMCE Toolbar button viewed in Firebug

 

If you just want to stick an image up on your toolbar button this might seem like rather more work than it needs to be, and you also probably want to keep your plugin self-contained and not rely on adding to the standard skin.

Fortunately, at least for simple toolbar buttons,  this is a lot easier than it might first appear.

Old school solution

TinyMCE 4’s example plugin doesn’t use a toolbar button icon at all, but this wasn’t the case with TinyMCE 3 which had a gif file for its toolbar button lurking in its img subdirectory. The plugin code references this file when it creates the toolbar button:-

// Register example button
ed.addButton('example', {
    title : 'example.desc',
    cmd : 'mceExample',
    image : url + '/img/example.gif'
});

And fortunately, if you check out the tinymce.ui.Button documentation you can see that exactly the same approach works with TinyMCE 4 too.

A Simple TinyMCE plugin layoutBy way of the simplest example possible, let’s create a toolbarplugin which just raises a browser alert when its button is clicked. All we need to do is add our button image file under an img sub-folder and then create a plugin.js with the following content:-

tinymce.PluginManager.add('toolbarplugin', function(editor, url) {
    editor.addButton('toolbarplugin',
        {title       : 'my plugin button',
         image       : url + '/img/toolbarplugin.png',
         onclick     : function() { alert('Clicked!');}});
});

Then add toolbarplugin to the plugins initialisation parameter and once more on the list of toolbar elements:-

<script type="text/javascript">
    tinyMCE.init({
        selector  : "textarea",
        theme     : "modern",
        plugins   : 'toolbarplugin',
        menubar   : false,
        statusbar : false,
        toolbar1  : 'undo redo | bold italic underline | ' +
                    'alignleft aligncenter alignright | ' +
                    'bullist numlist | toolbarplugin'
    });
</script>

And our plugin’s button appears complete with its custom icon:-

Simple TinyMCE Plugin in action

 

There’s an exception to every rule

This works fine with standard toolbar buttons, but if you are trying to add a MenuButton to your toolbar this approach will draw a blank. Literally.

The documentation for MenuButton includes the image parameter but the code doesn’t seem to use it; at least at TinyMCE 4.0.26 it only seems to use the icon setting that the standard buttons use. Fortunately you can use the same approach without too much extra work.

The icon setting used on the standard buttons references a CSS style which controls what gets displayed. For example in the above Firebug screenshot the Bold button has an icon setting of ‘bold’ which translates into a CSS style of .mce-i-bold:before which contains the character code of the appropriate symbol in tinymce.ttf.

Therefore, to use the same mechanism for a custom image file on a MenuButton you just need to add a CSS style matching this naming convention which references and displays your image.

Here’s how to do it.

Continuing the example above we’ll create a css sub-folder in our plugin and include in it a toolbarplugin.css file which looks like this:-

.mce-i-toolbarplugin {
    background: url('../img/toolbarplugin.png');
    height: 16px;
    width: 16px;
}

The next thing we need to do is add this CSS to those loaded on the parent page containing the TinyMCE editor (note this isn’t the TinyMCE document which contains CSS styles for the content instead). We can’t do this during plugin initialisation because it will run before the editor is fully created, but we can hook into the init event to do it:-

tinymce.PluginManager.add('toolbarplugin', function(editor, url) {
    editor.on('init', function() {
        var cssURL = url + '/css/toolbarplugin.css';
        if(document.createStyleSheet){
            document.createStyleSheet(cssURL);
        } else {
            cssLink = editor.dom.create('link', {
                        rel: 'stylesheet',
                        href: cssURL
                      });
            document.getElementsByTagName('head')[0].
                      appendChild(cssLink);
        }
    });

    editor.addButton('toolbarplugin', 
         {tooltip      : 'my plugin button',
          icon         : 'toolbarplugin',
          type         : 'menubutton',
          menu         : [{text    : 'Click me', 
	 	    	          onclick : function() { alert('Clicked!');}}]
	});
});

For everything other than geriatric Internet Explorer versions creating the link DOM element and adding it to the head is enough. For full cross-browser support though we need to cater for those IE7-huggers with the document.createStyleSheet alternative.

With our .mce-i-toolbarplugin CSS style defined and the CSS added to the main page we can switch our button to have a type of menubutton and assign our icon property to match our control name:-

A TinyMCE MenuButton with custom icon

 

One response to “TinyMCE 4 – Adding custom toolbar icons to a plugin

  1. Emanuele Ciriachi

    Thank you, exactly what I was looking for.

Leave a Reply

Your email address will not be published. Required fields are marked *