Add a TinyMCE button to WordPress post editor

Most themes and large plugin utilize the WordPress Shortcode API by adding code snippets that could be parsed inside of a page or post. One of the handy ways to present a UI behavior for your customers is by embedding the functionality to the TinyMCE editor as an extra button.

You need to create two files and embed them in your theme/plugin or create an extra piece of code (say, via another plugin) to trigger this behavior. The first file should be the JavaScript logic behind the button (as TinyMCE interaction is entirely JS-driven) and the second one is the WordPress handler that hooks your button and eventually adds some filtering/restriction logic behind that (related to plain PHP or the WordPress API).

editor_plugin.js


(function($, undefined) {
tinymce.create('tinymce.plugins.dx_demo_button', {
init : function(ed, url) {
ed.addButton('dx_demo_button', {
title : 'dx_demo_button.sample',
image : url+'/sample.png',
onclick : function() {
// define if the button lacks submenus
// ed.execCommand('mceInsertContent', false, '[sample id="' + someval + '"]');
}
});
},
createControl : function(n, cm) {
// display specific menus only for your button
if(n == 'dx_demo_button') {
var c = cm.createMenuButton('dx_sample_shortcodes', {
title : 'sample shortcodes',
});

// Define buttons for shortcodes
c.onRenderMenu.add(function(c, m) {
// Serves as a title
m.add({title : 'Shortcodes', 'class' : 'mceMenuItemTitle'}).setDisabled(1);

// two sample buttons that insert content
var first_shortcode = m.add({title:"First Shortcode", onclick: function() {
c.editor.execCommand('mceInsertContent', false, '[your_first_code]here[/your_first_code]');
}});

var menu_one_two_thirds = m.add({title:"Utilize function", onclick: function() {
c.editor.execCommand('mceInsertContent', false, dx_sample_function());
}});

});

return c;
}

return null;
},
getInfo : function() {
return {
longname : "DX Sample Shortcode",
author : 'Mario Peshev',
authorurl : '',
infourl : '',
version : "1.0"
};
}
});
tinymce.PluginManager.add('dx_demo_button', tinymce.plugins.dx_demo_button);

})();

function dx_sample_function() {
return '[dx_sample_shortcode_two]';
}

That’s our JS definition where we create the button and attempt to add it to the TinyMCE editor. The commented section allows us to define a behavior for a direct button click (i.e. a single activity that occurs on a button click) but I’ve decided to place two submenus to the button that define two random shortcodes. Note the naming convention, it should be consistent for the button name that you pick as it’s registered on several levels. You can output the data directly with the mceInsertContent command or call a custom function that prepares the string.


class DX_Sample_Shortcode_Buttons {

function __construct() {
add_action( 'init', array( $this, 'add_dx_sample_button' ) );

add_filter( 'tiny_mce_version', array( $this, 'my_refresh_mce' ) );
}

/* Add buttons */

function add_dx_sample_button() {
if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
return;
if ( get_user_option('rich_editing') == 'true') {
add_filter('mce_external_plugins', array( $this, 'add_dx_sample_tinymce_plugin' ) );
add_filter('mce_buttons', array( $this, 'register_dx_sample_button' ) );
}
}

/* Add button callbacks */

function register_dx_sample_button($buttons) {
array_push($buttons, "|", "dx_demo_button");
return $buttons;
}

function add_dx_sample_tinymce_plugin($plugin_array) {
$plugin_array['dx_demo_button'] = plugins_url( 'editor_plugin.js', __FILE__ );
return $plugin_array;
}

/**
* Hacky for refreshing the TinyMCE cache
* @param inr $ver
* @return number version
*/
function my_refresh_mce($ver) {
$ver += 3;
return $ver;
}
}

new DX_Sample_Shortcode_Buttons();

It’s a sample implementation that works as a plain script too (if you add the plugin headers). It initializes a class and registers the button to the TinyMCE area. There are several conditionals for permissions test where you could hook your own logic if needed, and there is a small hacky script that I found online (my_refresh_mce) that solves some caching troubles when the JS code decides to be super consistent and bulletproof for your button updates.

Running them both with the correct paths results in a brand new button to your TinyMCE editor. On the top of the JS file there is a link to an icon where you could style your button.

One thought on “Add a TinyMCE button to WordPress post editor

Your thoughts?