WordPress
Article

Adding Custom Functionality to the WordPress Visual Editor

By Tim Carr

The content editor is a key part of WordPress. It allows users to create and manage their content, galleries and videos, in a Visual WYSIWYG (what you see is what you get) view.

It also comes with a Text view, which allows users to insert or amend HTML within their content.

The WordPress Visual Editor is powered by the TinyMCE editor control, which provides the WYSIWYG view, as well as the formatting buttons you see:

TinyMCE visual editor

Thanks to the TinyMCE API and WordPress’ filter hooks, we can add our own functionality to the WordPress Visual Editor. Specifically, we’ll look at how to create and register a custom TinyMCE Plugin which wraps selected text in a CSS class.

Creating the TinyMCE Plugin

In your WordPress website, create the wp-content/plugins/tinymce-custom-class folder.

We’ll store our plugin’s files here, so next create a file called tinymce-custom-class.php, using the following code:

/**
 * Plugin Name: TinyMCE Custom Class
 * Plugin URI: http://sitepoint.com
 * Version: 1.0
 * Author: Tim Carr
 * Author URI: http://www.n7studios.co.uk
 * Description: TinyMCE Plugin to wrap selected text in a custom CSS class, within the Visual Editor
 * License: GPL2
 */

class TinyMCE_Custom_Class {

    /**
    * Constructor. Called when the plugin is initialised.
    */
    function __construct() {

    }

}

$tinymce_custom_class = new TinyMCE_Custom_Class;

This gives WordPress some information about our Plugin, and sets up our construct, where we’ll register our TinyMCE actions and filters.

WordPress TinyMCE Filters

TinyMCE provides two key filters for registering an element on the Visual Editor toolbar:

Before we call these filters, we want check we’re in the WordPress Administration screens. Add the following code to the __construct:

if ( is_admin() ) {
	add_action( 'init', array( &$this, 'setup_tinymce_plugin' ) );
}

Next, add the setup_tinymce_plugin function to perform some further checks:

/**
* Check if the current user can edit Posts or Pages, and is using the Visual Editor
* If so, add some filters so we can register our plugin
*/
function setup_tinymce_plugin() {

    // Check if the logged in WordPress User can edit Posts or Pages
    // If not, don't register our TinyMCE plugin
    if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
        return;
    }

    // Check if the logged in WordPress User has the Visual Editor enabled
    // If not, don't register our TinyMCE plugin
    if ( get_user_option( 'rich_editing' ) !== 'true' ) {
        return;
    }

    // Setup some filters
    add_filter( 'mce_external_plugins', array( &$this, 'add_tinymce_plugin' ) );
    add_filter( 'mce_buttons', array( &$this, 'add_tinymce_toolbar_button' ) );

}

This checks if the current logged in WordPress user can edit Posts or Pages. If they can’t, there’s no point in registering our TinyMCE Plugin for that User, as they’ll never see the Visual Editor.

We then check if the user is using the Visual Editor, as some WordPress users turn this off via Users > Your Profile. Again, if the user is not using the Visual Editor, we return (exit) the function, as we don’t need to do anything else.

If the above checks pass, the two TinyMCE WordPress Filters are registered – mce_external_plugins and mce_buttons.

The first filter – mce_external_plugins – allows us to register the TinyMCE JavaScript Plugin file that will interact with the Visual Editor. Let’s add a function call for this filter, inside our class:

/**
 * Adds a TinyMCE plugin compatible JS file to the TinyMCE / Visual Editor instance
 *
 * @param array $plugin_array Array of registered TinyMCE Plugins
 * @return array Modified array of registered TinyMCE Plugins
 */
function add_tinymce_plugin( $plugin_array ) {

    $plugin_array['custom_class'] = plugin_dir_url( __FILE__ ) . 'tinymce-custom-class.js';
    return $plugin_array;

}

Here, we register a JavaScript file within the $plugin_array, which contains all TinyMCE JavaScript plugins.

The second filter – mce_buttons – tells TinyMCE that we’d like to register a button in the Visual Editor. Again, let’s add a function call for this filter, inside our class:

/**
 * Adds a button to the TinyMCE / Visual Editor which the user can click
 * to insert a custom CSS class.
 *
 * @param array $buttons Array of registered TinyMCE Buttons
 * @return array Modified array of registered TinyMCE Buttons
 */
function add_tinymce_toolbar_button( $buttons ) {

    array_push( $buttons, 'custom_class' );
    return $buttons;

}

This registers the programmatic name for our TinyMCE button (custom_class).

Creating the JavaScript Plugin

When we called mce_external_plugins, we referenced a JavaScript file. We now need to create that file, and add some JavaScript code to it. This will tell TinyMCE how to output the button, and what to do when it’s clicked.

Create a new file in the plugin folder called tinymce-custom-class.js, inserting the following code:

(function() {
    tinymce.PluginManager.add( 'custom_class', function( editor, url ) {
        // Add Button to Visual Editor Toolbar
        editor.addButton('custom_class', {
            title: 'Insert CSS Class',
            cmd: 'custom_class',
            image: url + '/icon.png',
        });

        // Add Command when Button Clicked
        editor.addCommand('custom_class', function() {
            alert('Button clicked!');
        });
    });
})();

This JavaScript function performs a few actions:

  • It calls the TinyMCE Plugin Manager class, which we can use to perform a number of TinyMCE plugin related actions. Specifically, we’re adding our plugin to TinyMCE using the add function.
  • Within the add routine, we have access to the Visual Editor through the editor instance. We register our button using the addButton function, which comprises of a title, command and icon image.
  • Finally, we register a command using the addCommand function, which shows an alert telling us when our button was clicked.

We’ll need to also include the icon.png image within our Plugin folder – this is the icon image that will be used for the button:

TinyMCE

Save your code, and activate your Plugin in WordPress Administration > Plugins.

Next, create or edit a Page or Post, and you’ll hopefully see your button with the icon:

TinyMCE insert CSS Class

Click the button, and you’ll see the Button clicked! alert:

TinyMCE message

Defining a Command to Run

Let’s replace the alert with a prompt, asking the user for the CSS class name they want to wrap around the selected text in the Visual Editor:

(function() {
    tinymce.PluginManager.add( 'custom_class', function( editor, url ) {
        // Add Button to Visual Editor Toolbar
        editor.addButton('custom_class', {
            title: 'Insert CSS Class',
            cmd: 'custom_class',
            image: url + '/icon.png',
        });

        // Add Command when Button Clicked
        editor.addCommand('custom_class', function() {
            // Check we have selected some text selected
            var text = editor.selection.getContent({
                'format': 'html'
            });
            if ( text.length === 0 ) {
                alert( 'Please select some text.' );
                return;
            }

            // Ask the user to enter a CSS class
            var result = prompt('Enter the CSS class');
            if ( !result ) {
                // User cancelled - exit
                return;
            }
            if (result.length === 0) {
                // User didn't enter anything - exit
                return;
            }

            // Insert selected text back into editor, wrapping it in an anchor tag
            editor.execCommand('mceReplaceContent', false, '' + text + '');
        });
    });
})();

This command performs a few sanity checks, to make sure the user selected some text, entered a CSS class name and didn’t cancel the process.

If those checks pass, we then run the editor’s execCommand function, to replace the selected text, with the selected text wrapped in a span tag which includes the inputted CSS class.

If everything worked, switch to the ‘Text’ view, and you’ll see your selected text is now wrapped in a span tag:

TinyMCE code

Conclusion

We’ve created a WordPress Plugin to add a button to the TinyMCE Visual Editor. In this process, we’ve explored the filters WordPress uses for integration with TinyMCE, as well as the JavaScript code needed to add a button and perform an action when clicked.

To download the complete source code, visit the GitHub repository or the direct ZIP file download link.

In the next article, we’ll cover some more advanced steps that we can take to customize our TinyMCE plugin further.

  • http://www.bunce.space Mike Bunce

    That looks like a useful plugin. I generally like to limit my users as much as possible to their inputs, normally using custom fields that allow me to style their content through the theme. That way a client doesn’t have to have any knowledge of HTML or CSS and don’t get bewildered by the WYSIWYG editor.

    • http://www.n7studios.co.uk Tim Carr

      Great idea to use custom fields – I’d definitely recommend Advanced Custom Fields (or similar) to provide custom fields depending on the Page Template or Post Type, if the content needs specific styling. Plus you can provide some really specific inputs, content blocks, repeaters etc – great for more complicated Page layouts without using HTML.

      For smaller elements, such as inserting a button within the content (which the client might want to do anywhere), I find a small TinyMCE Plugin works well.

      • http://SalaryNet30.com Doreen Wheeler

        like Russell replied I’m stunned that a mom can profit $8748 in a few weeks on the internet. pop over to this website on `my` `prof1Ie`

        %555555555555

      • http://SalaryNet30.com Doreen Wheeler

        like Russell replied I’m stunned that a mom can profit $8748 in a few weeks on the internet. pop over to this website on `my` `prof1Ie`

        %555555555555

    • http://careersreport.com Jaime Grimes

      Here is something worth everybody’s attention , an excellent opportunity for work for those who want to utilise their free time to make some extra money using their computers… I have been working on this for last two and half years and I am earning 50-80 dollar/ hour … In the past week I have earned 13,245 dollars for almost 20 hours sitting ….

      There are no any special skills required for this, just basic typing and a good internet connection ….

      There are no time limitations … You may work on this any time when you are free ….

      check it what I’ve been doing….checkout siteIink on my profiIe` page` to see what I do`

      nmb

  • Jami Davidson

    Here is something to pay attention , a great opportunity for work for those who want to use their free time to make money using their computers… I have been doing this since last two years and I am making 40 to 70 dollars per hour … In the last week I have made 12,245 for almost 18 hours sitting ….

    ?There are no special skills required just basic typing and an internet connection ….

    ?There are no time constraints … You may do this any time when you are free ….

    ?Here is what I’ve been doing….

    < ->>w­w­w­.­y­o­u­c­a­n­a­l­s­o­c­h­a­n­g­e­y­o­u­r­f­a­t­e­l­i­k­e­o­t­h­e­r­s­a­r­e­.­b­l­o­g­s­p­o­t­.­c­o­m >

    %^&

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Instant Website Review

Use Woorank to analyze and optimize your website to improve your website to improve your ranking!

Run a review to see how your site can improve across 70+ metrics!

Get the latest in WordPress, once a week, for free.