Adding custom buttons in TinyMCE editor in WordPress

TinyMCE buttons

Create various buttons for TinyMCE Editor in WordPress

Today I’ll show you how to add your own custom buttons to TinyMCE Editor included with WordPress. I’ll be adding a button with which you can add columns in your editor. This however can be customized to your liking, to add certain classes, or stuff like that. As a base I’ll use Twenty sixteen theme. In your functions.php you’ll need to register the function which will modify the editor, and also include additional editor style. This is done so that when you add your columns, you can actually see them when writing – which is more user friendly.

add_action( 'after_setup_theme', 'mythemeslug_theme_setup' );

if ( ! function_exists( 'mythemeslug_theme_setup' ) ) {
	function mythemeslug_theme_setup(){
		/********* Registers an editor stylesheet for the theme ***********/
		add_action( 'admin_init', 'mythemeslug_theme_add_editor_styles' );
		/********* TinyMCE Buttons ***********/
		add_action( 'init', 'mythemeslug_buttons' );

Next, you’ll add the necessary functions

/********* Registers an editor stylesheet for the theme ***********/
if ( ! function_exists( 'mythemeslug_theme_add_editor_styles' ) ) {
	function mythemeslug_theme_add_editor_styles() {
	    add_editor_style( 'custom-editor-style.css' );

/********* TinyMCE Buttons ***********/
if ( ! function_exists( 'mythemeslug_buttons' ) ) {
	function mythemeslug_buttons() {
		if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {

	    if ( get_user_option( 'rich_editing' ) !== 'true' ) {

	    add_filter( 'mce_external_plugins', 'mythemeslug_add_buttons' );
	    add_filter( 'mce_buttons', 'mythemeslug_register_buttons' );

if ( ! function_exists( 'mythemeslug_add_buttons' ) ) {
	function mythemeslug_add_buttons( $plugin_array ) {
	    $plugin_array['columns'] = get_template_directory_uri().'/js/tinymce_buttons.js';
	    return $plugin_array;

if ( ! function_exists( 'mythemeslug_register_buttons' ) ) {
	function mythemeslug_register_buttons( $buttons ) {
	    array_push( $buttons, 'columns' );
	    return $buttons;

Now, the first is the registered editor stylesheet, and the second is the function for our buttons. In it you can check if you’re on post/page edit and if the rich text editor – TinyMCE is present. If those conditions are set, you can add filters that will modify the existing filters for the TinyMCE editor – mce_external_plugins and mce_buttons. If you want to know more about actions and filters I recommend an article Mastering WooCommerce Actions and Filters.

Notice that you have added the javascript file that will govern the behavior of the button, and you’ve added the name of your button to the existing buttons array called columns. This name is important because it acts as an identifier for your button. It’s best to give it a unique name.

Insert Column button in TinyMCE

A new button that you’ve added to your visual editor

JavaScript code

The code inside tinymce_buttons.js looks like this

(function() {
    tinymce.PluginManager.add( 'columns', function( editor, url ) {
        // Add Button to Visual Editor Toolbar
        editor.addButton('columns', {
            title: 'Insert Column',
            cmd: 'columns',
            image: url + '/columns.jpg',

        editor.addCommand('columns', function() {
            var selected_text = editor.selection.getContent({
                'format': 'html'
            if ( selected_text.length === 0 ) {
                alert( 'Please select some text.' );
            var open_column = '<div class="column">';
            var close_column = '</div>';
            var return_text = '';
            return_text = open_column + selected_text + close_column;
            editor.execCommand('mceReplaceContent', false, return_text);


Since TinyMCE editor is included with WordPress, you can readily use the options for it. We are adding a new button, so we are adding the columns to the tinymce object. First we add the button using addButton method. If you want to have translatable name I recommend localization. Just add the translatable string to the localized object and pass it to the title. The image needs to be located in the same file where the js file is located – or you can use localization to specify the path of the image to use. The command refers to the addCommand method. That method determines the functionality of your button. In our case we want to get the selected text and wrap it in a column div.

CSS part

To actually be able to visualize our columns we need the inline editor styles. In the custom-editor-style.css add

#tinymce .column{
	width: 48%;
	display: inline-block;
	vertical-align: top;
	margin-bottom: 10px;
	background: #F1F1F1;

#tinymce .column:nth-of-type(2n+2) {
    margin-left: 4%;

#tinymce .column img{
    max-width: 100%;
    margin: 0;
    margin-bottom: 10px;

This works for 2 columns – wraps the text in a div, and makes it approximately half the size, and adds a gray background so that you can see the column more clearly.

And that’s it. Simple enough. You can of course modify this to add different functionality. There are number of examples on the web.

Note about the usage of the columns – you need to write your text first, select the text you want in one column, push the button, select the text in the second column, push the button, and you’ll have properly formatted columns.

Formatted text using new button

Formatted text using new button for TinyMCE editor

Hope this helps with the creation of different buttons that you can use on your plugins as well. If you have anything to comment or ask, please do so below in the comment section. Happy coding!

Also published on Medium.

Join the Discussion