How to Create a WordPress TinyMCE Plugin: An Expert Guide

As a webmaster with over 15 years of experience working with WordPress, I‘ve customized my fair share of TinyMCE plugins. The WordPress visual editor is used on over 60% of sites, so chances are you‘ll need to extend it at some point.

In this comprehensive guide, I‘ll walk through exactly how to build a custom TinyMCE plugin from start to finish. I‘ll share some best practices I‘ve learned along the way to help you avoid common mistakes.

Why Extend the WordPress Visual Editor?

Before we dig in, let‘s look at some examples of why you may want to create a custom TinyMCE plugin:

  • Add custom buttons or tools – Perhaps you want to insert buttons, callout boxes or other elements not in the default editor. A plugin lets you extend the toolbar with new buttons that insert your custom markup.

  • Integrate with page builders – Page builders like Elementor have TinyMCE plugins to allow dragging content from the builder widget panels straight into the editor. This makes using page builders much smoother.

  • Enforce content formatting – Some developers create TinyMCE plugins that restrict formatting options or auto-apply certain CSS classes. This can help content adhere to your brand style guide.

  • Fix editor inconsistencies – TinyMCE can sometimes behave differently across platforms and browsers. A plugin can iron out quirks to make the editor more consistent.

  • Import content – You can add buttons to import content from external sources like Google Docs or markdown files right into the visual editor.

The possibilities are endless when you can customize TinyMCE! Next I‘ll show you how it works under the hood…

Anatomy of a TinyMCE Plugin

Before diving into code, it helps to understand how a TinyMCE plugin is structured:

TinyMCE Plugin Overview

Here are the key components:

  • Main plugin file – A PHP file that registers the plugin in WordPress
  • Admin javascript – JS logic that loads assets and initializes the plugin
  • Editor javascript – JS file with TinyMCE-specific logic that extends the editor
  • External assets – Images, CSS or other assets used by your plugin

Now let‘s walk through building each part of a real working plugin…

Step 1: Creating the Main Plugin Files

As with any WordPress plugin, we first need to set up our main PHP plugin file. This will register the plugin so it can be activated and used in WordPress.

Create a new folder /wp-content/plugins/ called tinymce-demo and add a tinymce-demo.php file:

<?php 

/**
 * Plugin Name: TinyMCE Demo
 * Description: Adds custom buttons to the editor.
 * Version: 1.0
*/

This contains the required WordPress plugin header comment.

Pro Tip: Use a namespaced function prefix like tinymce_demo_ to avoid conflicts with other plugins.

Next, create a /js/ folder within the plugin to hold our JavaScript files:

  • /tinymce-demo.php (Main Plugin File)
  • /js/admin.js (Admin JS)
  • /js/editor.js (Editor JS)

Now our basic file structure is set up!

Step 2: Enqueuing Scripts

For the plugin to function, we need to enqueue the required JavaScript on pages that have a TinyMCE editor instance.

In tinymce-demo.php add:

function tinymce_demo_scripts() {

  // Load only on admin pages 
  if ( ! is_admin() ) {
    return;
  }

  // Load for users with access to the editor
  if ( ! current_user_can( ‘edit_posts‘ ) && ! current_user_can( ‘edit_pages‘ ) ) {
    return;
  }

  wp_enqueue_script( ‘tinymce-demo-admin‘, plugins_url( ‘js/admin.js‘, __FILE__ ), array(‘jquery‘), ‘1.0‘, true );

}

add_action( ‘admin_enqueue_scripts‘, ‘tinymce_demo_scripts‘ );

This ensures we only load the script when needed on admin pages. Pro Tip: Avoid enqueueing JS globally as it can impact performance.

Now let‘s add our main editor logic…

Step 3: Initializing the Plugin

Within js/editor.js, we need to register our plugin:

(function() {

  tinymce.PluginManager.add( ‘tinymce_demo‘, function( editor, url ) {

    // Add functionality here next

  });

})();

This creates a new tinymce_demo instance. Inside here we can extend the editor.

To initialize the plugin, include this in js/admin.js:

jQuery( document ).ready( function($) {

  if ( typeof tinymce !== ‘undefined‘ ) {

    tinymce.init({
      selector: ‘.wp-editor-area‘,
      plugins: [ ‘tinymce_demo‘ ] 
    });

  }

}); 

This will load the plugin on editors matched by the CSS selector.

Pro Tip: Use specific selectors like textarea#content to only load on certain editor instances.

Step 4: Adding Custom Toolbar Buttons

Now let‘s add a new button to the toolbar.

In editor.js, add:

editor.addButton( ‘tinymce_demo‘, {
  title: ‘Demo button‘,
  icon: ‘dashicon dashicons-text-page‘,
  onclick: function() {
    // Button logic
  }
});

We defined the button name, label, icon and click handler.

To display the button, filter the toolbar row:

editor.on( ‘init‘, function( evt )  {
  editor.settings.toolbar1 += ‘,tinymce_demo‘;
});

This will append our button to the first row. You can add to any row like this.

Pro Tip: Use existing Dashicons for simple icons. For custom images, reference a CDN URL.

Step 5: Defining Button Functionality

When the button is clicked, we can insert content into the editor:

onclick: function() {

  var selectedText = editor.selection.getContent();

  if ( ! selectedText ) {
    alert( ‘Please select text first.‘ );
    return;
  }

  editor.insertContent(‘<span class="highlight">‘ + selectedText + ‘</span>‘);

} 

Here we wrap the selected text in a <span> to apply a highlight class.

We can also open popups for more complex UIs:

onclick: function() {

  editor.windowManager.open( /* settings */ );

}

The possibilities are endless!

Step 6: Installing and Testing your Plugin

To test our plugin:

  1. Upload the tinymce-demo folder to your /wp-content/plugins/ directory
  2. Activate the plugin in WordPress
  3. Edit a page and you should see the new toolbar button
  4. Test clicking the button and confirm the functionality works

Here are some common issues and fixes:

Button not showing? Confirm you added it to a toolbar row like toolbar1.

Script not loading? Check the console for enqueue errors.

Errors on click? Make sure you defined the onclick handler.

With some tweaking, you‘ll have your custom editor extension up and running in no time!

Going Further with TinyMCE Development

To take your TinyMCE skills even further, I recommend:

The WordPress editor is used by over 100 million websites, so it‘s a great platform for distributing your own custom editor extensions.

I hope this guide gave you a solid foundation for creating TinyMCE plugins. Let me know if you have any other questions!

Written by Jason Striegel

C/C++, Java, Python, Linux developer for 18 years, A-Tech enthusiast love to share some useful tech hacks.