Custom TinyMCE Buttons in WordPress

Creating your own custom TinyMCE buttons is a great feature that can add a lot of value to your WordPress plugin or theme. Adding a TinyMCE button to your editor makes it easy for the user to add your shortcodes or buttons that generate custom styles beyond the default HTML tags like <blockquote> and <strong>.

tinymce-logo

In a future tutorial I will go over adding some of the already existing buttons that are hidden by default in WordPress, but for this week I’ll concentrate on creating your own custom buttons. All the custom buttons will be added in a WordPress plugin and I will create an example plugin like the one’s I did for the Media Library and WordPress AJAX example plugins.

Also for anyone who would rather just check out the example plugin instead of read through this article, you can download it from GitHub here.

The Main Plugin File

The first thing we have to do is create our main PHP file for our plugin. For those who don’t already know the basics of creating a plugin – I’ve created a tutorial that walks through the basics step by step. I would highly recommend check that out before going through this since I’ll go quickly and I won’t explain everything. The basic process boils down to four things for this plugin though:

  1. Create the main plugin file
  2. Create the JavaScript file that will contain our TinyMCE plugin code
  3. Create our CSS file which we will need for custom icons and dashicons
  4. Add a folder for our custom icon image files

Since I’ve called my plugin “DobsonDev WordPress TinyMCE Example” and I’ve named the folder dobsondev-wordpress-tinymce-example, I’ve opted to name my main file dobsondev-wordpress-tinymce-example.php. The basic information for the plugin is as follows:

Hooking in the CSS

The first call I want to make in my main plugin file is the call that hooks in our CSS file. The CSS will be required when we want to use custom icons as well as dashicons for our menu items. This can easily be done with the following code (all code in this tutorial will be taken directly from the example plugin):

All code examples are taken directly from the example plugin!

As you can see I use dobsondev_tinymce_example as the slug for my function titles. I’m not sure why but I’ve always used really long slugs, but if you are making your own version of the plugin feel free to change that to whatever works for you (but make sure it’s unique!).

The Main Function

Next up we have what I call the main function for our custom TinyMCE plugin. This function does 3 four things:

  1. Checks that the current user has permissions to edit posts and pages
  2. Checks that we are editing a post or page
  3. Checks that rich editing is enabled
  4. Calls the filter functions that will add our custom buttons

The first three steps are done with simple checks and the one is done by simply calling the add_filter( … ) function built into WordPress. This function is added as an action to the admin_head since we only need to load our plugin when editing a post or page which takes place on the admin side. You can see the code below:

After this main function we only have to create the two functions that we call in our add_filter( … ) function calls before we are done with our main plugin file. One very important thing to note is the number 3 at the end of mce_buttons_3 in the add_filter( ‘mce_buttons_3’, ‘dobsondev_tinymce_example_register_buttons’ ) call. This denotes the row that the buttons will appear on. For this plugin I opted to put all the buttons on the third row to differentiate them from the rest of the default buttons but you can change that number to change the row.

Change the number in mce_buttons_ to change the row the buttons appear in

Adding the Plugin File to TinyMCE

The next task we want to do is make the dobsondev_tinymce_example_add_tinymce_plugin function that we call in our main function (it’s the first add_filter( … ) call). This function basically gives WordPress the path to our JS file (which we will create next) so that TinyMCE can use it and load our plugin.

The function takes the array of currently loaded plugins and then the function simply adds our own to it and then returns the array. You can see the code below:

Adding the Buttons to TinyMCE

The final function we have to create is the dobsondev_tinymce_example_register_buttons function. This function takes in the current TinyMCE buttons as a $buttons array and then we will add our own buttons to that array and return it. It works in a very similar way to the dobsondev_tinymce_example_add_tinymce_plugin function but with the buttons rather than the plugin files.

Each of the buttons listed below are defined in the tinymce-example-plugin.js file. We will get to this part next but for now you just have to know that for each button you create in your plugin file, you have to include an array_push( … ) call for it.

We will go through all these different buttons right away!

And that’s all there is in the main plugin PHP file. Next we can move on to the TinyMCE plugin file and creating the buttons that we listed out in the dobsondev_tinymce_example_register_buttons function.

The TinyMCE Plugin JS File

Our next task is to actually create the buttons we’ve already defined by creating a TinyMCE plugin JavaScript file. This file can go anywhere in your plugin structure, but for my plugin I put it under js/tinymce-example-plugin.js. The only thing to watch for is to make sure you put it where you said you did in your dobsondev_tinymce_example_add_tinymce_plugin function from the main plugin file. As long as you put the file path and the file name in that function you can name it and put it anywhere you want.

One of the first things I want to go over is the basic layout of the plugin file. The way my example plugin works is that is has the normal wrapper that you would use and then it contains 9 different buttons within that basic wrapper. This is of course probably not what you’re going to do for your theme or plugin. The point of my example plugin is to show you how to do a variety of different types of buttons so you have a code base for anything you might want. You’re theme addition or plugin will most likely only contain one or two buttons at most, maybe with drop downs in those buttons.

The basic layout of a plugin is as follows (at least as far as adding your own buttons is concerned):

Use this basic wrapper when adding buttons in your plugin!
Make sure you change the name to the same one you defined in your plugin_array!

This basic wrapper can be used for pretty much any situation involving adding buttons. The only thing you’ll have to change is the dobsondev_tinymce_example_plugin to whatever name you gave your plugin in your dobsondev_tinymce_example_add_tinymce_plugin function. As long as you do that everything should work.

As you can also see from the function above, I’ve included a comment where you’re button code will go. Every time you need to create a button there is just a simple function call to the editor JavaScript passed in to the wrapper TinyMCE function (tinymce.PluginManager.add( …, function ( editor, url ) {). This is the basic layout that you’ll always use and as you see some examples it should all come together.

Next we’ll look at our first button code example. While doing that code example I’ll explain a little more about how everything works with the wrapper so hopefully everything comes together for anyone still confused. If you ever want more information, check out TinyMCE’s tutorial on creating a plugin for more information.

Text Button

A text button is probably the most simple and easy to implement button you can add in a TinyMCE plugin. Check out the code for a text button below:

Use the same button name as the one you defined in your register buttons function!

As you can see the call to create a button is just a simple function call to the editor object (as I mentioned above). From here you have to give your button a name. This name has to be the same name that you used in your dobsondev_tinymce_example_register_buttons function. Most likely you will create the button first and then create the registration function after but just make sure they have the same name.

Once you’ve named you button there are a variety of properties that you can set for your button. For a text button you definitely want to set the title, text, icon and if you actually want it to do something the onclick.

  • The title will be displayed in a little popup when you mouse over the button.
  • The text will be the actual text that is displayed on the toolbar on the TinyMCE editor.
  • If you have no icon that you want to use, it’s a good idea to explicitly tell TinyMCE that by defining icon as false.
  • Finally the onclick should be defined as a function that will insert whatever text you want when the button is pressed. This supplies the functionality for the button.

In the onclick function you can see that we use editor.insertContent( String content ) to insert whatever text we want to the page. There is an alternative way to do this if you want to however. You can – if it makes more sense to you – defined a value property and then pass that to the editor.insertContent( … ) function call instead. You can see this alternative method below:

Fitting this into the Wrapper

As mentioned when I went over the TinyMCE plugin wrapper I’m going to go over how adding a button with the wrapper works here. It really is pretty simple but I want to show some complete code examples so you see how it works. First we have the text button example with the wrapper:

Next we have the alternative text button that uses the value property:

And finally we have an example where both the original text button and the alternative method are included within the wrapper. This method will produce two buttons that look exactly the same but I think it illustrates how to add two buttons to your plugin wrapper:

As you can probably see from these examples – adding the buttons really is as simple as putting their function(s) into the middle of the wrapper. That’s really all there is to it!

Icon Labelled Button

The next example we’ll look at is a button that is labelled with a standard dashicons icon. Note that some of the dashicons (the standard ones) are included in the editor and don’t require any CSS changes. However there are other dashicons that will require some CSS in order to work. We will get to an example of that next. For now check out this example of a standard icon:

The only changes we’ve really done from the examples above is taken out the text property (we’ll do an example of an icon with a text label in a bit) and added an actual value to the icon property. If you click on the following link of all the available dashicons and then scroll down to the TinyMCE section – you’ll find all the standard icons you can use since they should all be defined in the code editor.

Dashicons Labelled Button

If you want to use a dashicons icon that isn’t defined in the editor (aka is not a part of the standard set) then we’ll need to do a little bit of CSS work. First let’s take a look at the JavaScript code which looks very similar to the previous example:

If you use this by itself then the icon will not load. However, you can add the following CSS to your css/tinymce-example.css file to get it to work (again this file name and path can be changed as long as you change it in your main plugin PHP file as well):

Adding that code will enable you to use any of the dashicons you want as long as you follow the same format (remember to include that icon followed by the name of the dashicon). Again, click on the following link to check out all the available dashicons.

Custom Icon Labelled Button

Next we’re going to switch it up from a dashicons icon to a custom made icon. The icons you make should be 64px by 64px .png file. Once you have the file upload it to your plugin (I put mine in a imgs folder but you can do whatever. Once you’re done that use the following JavaScript (change the name of the icon to whatever it is):

and then use the following CSS to get everything to work:

Again all the file paths and names can be changed so long as they’re correct in all files. Once you have everything done you will see a button with your custom icon on it.

Remember to use a 64px by 64px .png image as your icon

Icon and Text Labelled Button

Now seems like a good time to go over how to create a button with both an icon and text label. If any of you were thinking that it’s probably just a simply as having both a icon and text property – congratulations! You’re totally right! It really is as simple as having both. Converting the example above to have an icon as well as text, we would have the following JavaScript:

In the example plugin I’ve made there are a number of examples that are first just labelled with an icon and then labelled with an icon and text. This is just so people using it can see how they look – but for the rest of this tutorial I won’t go over both examples since you can download the plugin yourself and adding text is as easy as adding a text property.

Sub Menu Button

Next we’ll look at a button that when pressed produces a drop down menu with more selections in it. You can see the JavaScript code below:

The first thing you might notice is that the top level has two new properties added to it, first we have type: ‘menubutton’. This will make the button into a drop down menu. From there you also have to add a new menu property. This property defines what will be contained in the drop down menu (or sub menu as it might get called). In the menu property we just want to include more button objects like we have done in previous examples.

Sub Sub Menu Button

Now that we’ve covered sub menu buttons – let’s take a look at giving those sub menu’s sub menus of their own (ie sub sub menus). Check out the JavaScript code below:

The main thing to note and that needs to change here from the previous sub menu example is that fact that the sub sub menu is not located under a button that has a type: ‘menubutton’. Rather it is located under a normal text button. This creates one problem for us – if we click on the sub sub menu item then both the sub menu value and the sub sub menu value get output to the editor. In order to combat that we use e.stopPropagation(), which will stop the sub menu item value from outputting and only output the sub sub menu value.

This is all assuming that you want the first level sub menu button to produce some kind of output. If you don’t want the sub menu item to have any output then of course set it so that it has type: ‘menubutton’. If you do that then you won’t have to use the e.stopPropagation() call.

Popup Window Button

Finally we have a button that produces a popup window where you can fill in information. This is extremely useful if you plan on outputting a shortcode that requires attributes you want the user to fill in. Check out the JavaScript code and then we’ll go through the tricky bits:

All of the new code that we have to do is located in the onclick function. From here we want to enable a popup window by calling editor.windowManager.open( … ). Once we do that there are a few properties that we need to include – title and body. The body parameter will contain objects that will define all the fields you want the user to fill out. These field objects consist of type, name and label properties.

Once you have all your properties defined for both your body and the field objects – you want to define an onsubmit function. This will output the text from the field objects once everything is filled out in the popup. In order to access the information you want to call e.data. and then include the name of the field object at the end.

Popup windows in TinyMCE are some of the most dynamic fields you’ll want to have – so practice with this one and mess around with the fields. One of the most obvious uses is shortcodes but try anything you can think of.

Conclusion

This was a long tutorial but I hope it helped a lot of people. You can download the example plugin from GitHub here. Install it on your WordPress install and play around with it!

As always thank you for reading and please share it around as much as you can! Please feel free to put any suggestions or ideas for future tutorials in the comments section below. Also let me know about any buttons you would want included in your WordPress install!