Dissecting the WordPress TinyMCE Editor

By Carlo Daniele Updated on August 28, 2018

This is the second part of two posts dedicated to WordPress editors. The first post was all about WordPress text editor, while in this post we will dissect the WordPress TinyMCE editor, and we will bend it to our will. Follow along below as we will show you how to:

WordPress TinyMCE

TinyMCE is a browser-based WYSIWYG editor written in JavaScript and released as open source software under LGPL

WordPress TinyMCE editor

By default, WordPress the TinyMCE editor provides two rows of buttons to create, edit and format post content. The first row (the primary toolbar) includes styling and formatting functionalities. Additional controls allow to add, edit and remove anchors, add the <!–more–> tag, activate the distraction-free mode. All these buttons should look pretty familiar to anyone with basic knowledge of a word processor.

The Toolbar Toggle button toggles the Advanced editor toolbar (the second row of buttons), which provides a pulldown menu of text elements (paragraph, headings and preformatted text), more styling controls, and some additional features (Paste as text, Clear formatting, Special characters, Undo and Redo) that come in handy in many ways.

Special characters

The Special characters table allow users to quickly add HTML entities

Finally, the question mark button provides a list of keyboard shortcuts which improve the user writing experience.


The TinyMCE shortcuts panel

Now add and style your content into the visual editor, then switch to the text editor. You’ll find the corresponding HTML structure as WordPress will preserve your input when switching from visual to text mode.

Default primary and advanced toolbars provide a good number of functionalities which can be extended with additional buttons and controls. Many of these buttons are available out of the box in TinyMCE, and we just need to activate them to put them in action. Moreover, we can add a good number of advanced functionalities by installing one or more of the existing plugins.

And if all these buttons are not enough, we can enhance the editor with your coolest functionalities, by developing custom plugins.

That being said, let’s start diving from the easiest and most common usage of the API.

Adding custom styles to WordPress TinyMCE editor

Assume you need to provide an easy way to add custom styles into post content from TinyMCE. It’s a two step procedure:

  • first, we need to activate a hidden pulldown menu named Styleselect,
  • then we have to define each style we want to add to the Styleselect menu.

We can accomplish the first task by filtering the array of TinyMCE buttons. The default toolbar shows one or two rows of buttons, but we can enable up to four toolbar rows thanks to the following filters:

  • mce_buttons filters the primary toolbar buttons (the first row), which is always visible;
  • mce_buttons_2 filters the advanced toolbar buttons (the second row), which can be toggled on/off by the user;
  • mce_buttons_3 inactive by default;
  • mce_buttons_4 inactive by default.

We can hook a callback function to one of these filters to show/hide existing buttons, like the Styleselect pulldown menu. The following function enables the menu in the second row:

function my_mce_buttons_2( $buttons ) {
	array_unshift( $buttons, 'styleselect' );
	return $buttons;
add_filter( 'mce_buttons_2', 'my_mce_buttons_2' );

The array_unshift PHP function prepends the styleselect element to the front of the $buttons array.


The Format dropdown menu will show a list of all available CSS styles

Now that the button has been activated, we can register our custom styles by filtering an array of TinyMCE configuration parameters through the tiny_mce_before_init filter.
Consider the following function:

function my_tiny_mce_before_init( $mceInit ) {
	$style_formats = array(
			'title' => 'PHP',
			'block' => 'code',
			'classes' => 'language-php'
	$mceInit['style_formats'] = json_encode( $style_formats );	
	return $mceInit;    
add_filter( 'tiny_mce_before_init', 'my_tiny_mce_before_init' );

The style_formats element is a JSON encoded array of elements. Each element sets the configuration parameters of a single menu item. The function above replaces default styles with a single custom element which wraps the selected text in a code.language-php element.

style formats

The Styleselect dropdown menu containing a single custom item

In our example, we set three properties for a single menu item:

  • title: the title for the menu item;
  • block: the block element to produce;
  • classes: space separated list of CSS classes to apply to selection.

We added the code element as block, so that it will be applied only once to the full selection. Adding it as inline element would apply the code tag to each selected line.

We can add more items and group them by category, as shown in the following example:

function my_tiny_mce_before_init( $mceInit ) {
	$style_formats = array(
			'title' => 'Code language',
			'items' => array(
					'title' => 'PHP',
					'block' => 'code',
					'classes' => 'language-php'
					'title' => 'CSS',
					'block' => 'code',
					'classes' => 'language-css'
					'title' => 'HTML',
					'block' => 'code',
					'classes' => 'language-html'

	$mceInit['style_formats'] = json_encode( $style_formats );
	return $mceInit;    
add_filter( 'tiny_mce_before_init', 'my_tiny_mce_before_init' );

The style_formats element is a multi-dimentional array of parameters. In this example, we’ve added a first level item (Code language) and three sub items (PHP, CSS, HTML). The image below shows the resulting menu.

advanced style formats

We can group menu items and reduce the menu size on the screen

TinyMCE applies the styles to the selected elements, but is not aware of these styles, so they won’t be applied to the content in the editor. If a real-time preview is needed, we’ll have to register a custom stylesheet with the add_editor_style() function:

 * Registers an editor stylesheet for a custom theme.
function my_theme_add_editor_styles() {
	add_editor_style( 'css/my-editor-style.css' );
add_action( 'admin_init', 'my_theme_add_editor_styles' );

This function registers a stylesheet that will be used by WordPress TinyMCE to style content into the editor.
As an example, let’s suppose we’d like to apply different colors to PHP, CSS and HTML code. To accomplish this task, we’ll add the following declarations into css/my-editor-style.css stylesheet:

.language-php{ color: red; }
.language-css{ color: green; }
.language-html{ color: blue; }

TinyMCE will produce the output shown in the following image.

add editor styles

Note: We’ve looked at just few configuration settings, but TinyMCE API gives developers a great control over the editor. See TinyMCE documentation for the full list of elements and properties with some examples of usage.

Enabling WordPress TinyMCE hidden buttons

We can add buttons to the visual editor in several ways. In many cases we are not required to build a custom button because TinyMCE provides a good number of hidden buttons we can easily activate.
One of these buttons is the Styleselect dropdown menu, but we have a long list of inactive buttons we can activate by filtering the arrays of buttons through one of the mce_buttons_{n} filters (see TinyMCE docs for the full list of available buttons).

Consider the following example:

function my_mce_buttons_3( $buttons ) {	
	$buttons[] = 'superscript';
	$buttons[] = 'subscript';
	return $buttons;
add_filter( 'mce_buttons_3', 'my_mce_buttons_3' );

The callback function above adds the superscript and subscript elements to the end of the array $buttons.

The image shows two extra buttons added to the third row of TinyMCE toolbar

The image shows two extra buttons added to the third row of TinyMCE toolbar

Here is a list of hidden buttons available in WordPress TinyMCE:

  • cut
  • copy
  • paste
  • hr
  • formatselect
  • fontselect
  • fontsizeselect
  • styleselect
  • subscript (previously sub)
  • superscript (previously sup)
  • backcolor
  • newdocument
TinyMCE toolbar

The image shows the TinyMCE toolbar full of all the available buttons

If none of these buttons suits our needs, we can provide the editor with more functionalities, thanks to a good number of official plugins.

Enhancing the visual editor with TinyMCE plugins

Suppose your goal is to include the TinyMCE Table button into the visual editor through a WordPress plugin.

First, you have to download the Dev Package from TinyMCE website. Unpack the zip file and get the plugin.min.js file from /js/tinymce/plugin/table folder.

Create the following folders in /wp-content/plugins:

  • /wp-content/plugins/tinymce-example-plugin/
  • /wp-content/plugins/tinymce-example-plugin/mce/table

When you’re done, create a new tinymce-example-plugin.php file into the plugin root folder, and upload the plugin.min.js file into the table folder (see the image below).

The image shows the plugin file structure

The image shows the plugin file structure

Now add the following lines into tinymce-example-plugin.php:

 * @package TinyMCE_example_plugin
 * @version 1.0
Plugin Name: TinyMCE example plugin
Plugin URI: http://wordpress.org/extend/plugins/#
Description: This is an example plugin 
Author: Your Name
Version: 1.0
Author URI: http://yourdomain.com/

In order to include the Table button into the WordPress TinyMCE editor we just need two filters:
mce_buttons adds new buttons to TinyMCE primary toolbar (we can use any of mce_buttons_{n} filters, depending on the row where the button has to be shown)
mce_external_plugins loads an external TinyMCE plugin.

Here is the code of the plugin file:

function example_plugin_register_buttons( $buttons ) {
   $buttons[] = 'table';
	return $buttons;
// add new buttons
add_filter( 'mce_buttons', 'example_plugin_register_buttons' );

function example_plugin_register_plugin( $plugin_array ) {
   $plugin_array['table'] = plugins_url( '/mce/table/plugin.min.js', __FILE__ );
   return $plugin_array;
// Load the TinyMCE plugin
add_filter( 'mce_external_plugins', 'example_plugin_register_plugin' );

The first function adds a new button to the primary toolbar, while the second function loads a plugin from the specified URL. The plugins_url() function retrieves the absolute URL to the specified file under the plugin directory (read more on the Codex).

Now we can save the file and activate the plugin. The image below shows the enhanced toolbar.


That’s all. Following the same procedure, we can add any existing TinyMCE plugins to the WordPress visual editor.

You can download the plugin .zip file, or view the PHP code of this example on Gist.

Building a TinyMCE plugin

Finally, we can build our TinyMCE custom plugin. Suppose you want to add a button to allow users to wrap the selected content in the following tags:

<pre><code>Selected text</code></pre>

We can even decide to add a CSS class to the <code> tag, to provide support for Prism code highlighter. We need to:

  • register a custom TinyMCE button and plugin in a WordPress plugin;
  • develop the TinyMCE plugin;

We already know how to register a plugin and add a button in WordPress TinyMCE:

function example_plugin_register_buttons( $buttons ) {
	$buttons[] = 'prism';
	return $buttons;
// add new buttons
add_filter( 'mce_buttons', 'example_plugin_register_buttons' );

function example_plugin_register_plugin( $plugin_array ) {
	$plugin_array['prism'] = plugins_url( '/mce/prism/plugin.js', __FILE__ );
	return $plugin_array;
// Load the TinyMCE plugin
add_filter( 'mce_external_plugins', 'example_plugin_register_plugin' );

This is exactly the same code as the previous example, with the only difference that now we’re are registering a custom plugin named prism.
Now let’s create the following plugin.js file:

Looking for ways to improve your WordPress development workflow?

Kinsta’s hosting solution was built by developers for developers. Git, PHP 7, SSH, and WP-CLI, along with powerful staging and cloning environments gives you the tools you need to build sites faster!
(function() {
	var languages = ['css', 'php', 'html', 'javascript'];
	tinymce.PluginManager.add( 'prism', function( editor ){
		var items = [];

		tinymce.each( languages, function( languageName ){
				text: languageName,
				onclick: function(){
					var content = tinyMCE.activeEditor.selection.getContent();
					editor.insertContent( '<pre><code class="language-' + languageName + '">' + content + '</code></pre>' );

		editor.addButton( 'prism', {
			type: 'menubutton',
			text: 'Prism',
			icon: 'code',
			menu: items


This code is also available on Gist.

It’s not in our goals to dive into TinyMCE APIs, and you’ll find all you need to know in TinyMCE docs for developers.
This file should be placed in /mce/prism/ subfolder of our plugin directory. The JS function iterates among the elements of the languages array and pushes a new object into the items array for each language. The addButton method creates the Prism menu button, and adds a menu item for each element of the items array.

Save, upload and refresh, and your gorgeous dropdown menu button will pop up in all its beauty.

prism menu button

Any further information on how to develop TinyMCE plugins can be found in the online documentation for developers.

TinyMCE Advanced plugin for WordPress

If you’re not a developer, you can enhance the visual editor as well. TinyMCE Advanced is a free WordPress plugin which brings the functionalities of fifteen TinyMCE plugins to the default visual editor.

Thanks to TinyMCE Advanced users will add, remove, rearrange buttons on the four rows of the editor toolbar. In addition, the plugin provides an option to enable a menu above the toolbar.

TinyMCE Advanced provides a comprehensive list of editor settings

From the editor settings page we can add, remove and arrange buttons on TynyMCE toolbar

From the plugin options page we can enable several advanced features, like the Table button, the Font Family and Font Size menus, the Show blocks and Show invisible characters buttons.

Other options allow users to determine the editor that will be affected by new settings, and more.

From the editor settings page we can add, remove and arrange buttons on TynyMCE toolbar

TinyMCE Advanced provides a comprehensive list of editor settings


TinyMCE API provides a lot of stuff to play with. We can activate hidden functionalities or register external plugins. And if none of the available features is enough for us, we can have fun with the API and build custom extentions. Do you have any further ideas to enhance the WordPress TinyMCE editor?

If you enjoyed this article, then you'll love Kinsta's WordPress hosting platform. Whether it's speeding up your website or getting 24x7 support from our veteran WordPress team, we're here to help your business succeed. Our Google Cloud powered infrastructure focuses on auto-scaling, performance, and security. Let us show you the Kinsta difference! Check out our features

Hand-picked related articles

Comment policy: We love comments and appreciate the time that readers spend to share ideas and give feedback. However, all comments are manually moderated and those deemed to be spam or solely promotional will be deleted.
  1. Gravatar for this comment's author
    Neal Umphred December 7, 2016 at 10:21 am


    Thanks for the article on a very handy plugin.

    Now, how do we get the TinyMCE people to add the “1/3” option to the Special Characters?

    First time I went there to use it and found it not included, I was baffled!


    1. Gravatar for this comment's author
      Carlo Daniele December 7, 2016 at 1:26 pm

      Hi Neal. TinyMCE provides two settings that allow to manipulate the special chars map:

      charmap overwirtes default charset
      charmap_append adds custom characters to the charmap

      Add the following code to our example plugin:

      function example_plugin_special_chars( $settings ) {
      $new_chars = json_encode( array(
      array( ‘8531’, ‘One third’ )
      ) );
      $settings[‘charmap_append’] = $new_chars;
      return $settings;
      add_filter( ‘tiny_mce_before_init’, ‘example_plugin_special_chars’ );

      It works for me. Here you’ll find some useful readings and resources:



      1. Gravatar for this comment's author
        Neal Umphred December 12, 2016 at 12:36 pm


        Thanks for the response, but I don’t play with code unless I can add it to my Simple Custom CSS field.


        1. Gravatar for this comment's author
          Carlo Daniele December 13, 2016 at 8:13 am

          Hi Neal. You can download the example plugin here: http://carlodaniele.it/main/wp-content/uploads/2016/12/tinymce-example-plugin.zip
          Maybe I will work on this plugin a bit in the near future. I will send you an update

  2. Gravatar for this comment's author
    Adam Abrams December 14, 2017 at 12:12 pm

    Hi Carlo! Hey, I’m trying to get TinyMCE (within WordPress) to convert common special characters like curly quotes and em dashes to HTML entities – AND to leave these as such in the Text editor. Right now, if I type or paste-in such a character in the visual editor, it simply appears the same way in the text editor – i.e. an actual curly quote, not the “’” code, which is what I actually need. I’ve been all over the Web wrangling info about UTF-8, TinyMCE, filters, functions and hooks, but a solution to this remains elusive. (And I’m a modest-level coder – comfortable with HTML, CSS and some PHP but still in need of examples most of the time; the WP Codex alone is daunting!).

    Is what I’m looking for actually achievable? I hope you can provide some insight when you have a moment. Thanks!

    1. Gravatar for this comment's author
      Carlo Daniele December 18, 2017 at 9:39 am

      Hi Adam, thanks for your comment.

      Actually, it’s not that easy to prevent tinymce editor from converting characters, but still, it’s possible. First off, I suggest a reading of these interesting tickets:


      I think you may implement the tinymce visualchars plugin: https://www.tinymce.com/docs/plugins/visualchars/

      “This plugin adds the ability for users to see invisible characters like   displayed in the editable area. It also adds a toolbar control and a menu item Show invisible characters under the View menu.”

      Another good reading is this thread on stackexchange: https://wordpress.stackexchange.com/questions/54398/how-can-i-stop-tinymce-from-converting-my-html-entities-to-characters

      Let us know if this helps you.

  3. Gravatar for this comment's author
    Adam Abrams December 22, 2017 at 1:15 pm

    Carlo – thanks again for your invaluable help. Thanks to the second link you sent, I was able to finally realize how and why I was getting “” characters even in empty space, which had always baffled me…

    Ultimately, I worked up this brief custom function based on the last link you sent, and added it to my theme’s functions.php – it simply makes some changes to the Tiny MCE preferences, and the result is that the left and right curly single and double quote, em and en dash, and a few other common special characters, get swapped in with HTML entities, which display nicely in the visual editor, but remain when you switch back and forth to the text editor. And my mailing list software, which was showing the glitchy characters in its email messages when I sent a WordPress page, even though they did not display on the page itself, is now sending the messages perfectly!

    Here’s the function:



  4. Gravatar for this comment's author
    JJ September 13, 2018 at 1:26 pm


    On places like StackExchange and StackOverflow, there is an option to use what appears to be a version of TinyMCE as a field to comment on posts, as well as to upload visual images….

    It looks very similar to how I want TinyMCE to display on my own site.

    Problem is, on my WordPress site, know what’s there right now? Well…..when you get to the page on my site where TinyMCE is at, the first thing it displays is the “Text” editor…..not the Visual editor. Yet every single “help” article I see seems to say that TinyMCE tends to show, by default….the Visual editor (and people all seem to want to disable it). I have the opposite issue.

    So what I need — I need TinyMCE to display, without any clicking on behalf of the user, the “Visual” editor…..for it to be already “open” on the page and displaying when the user gets to that page. I’ll be disabling the Text editor. And its tabs (as well as the tabs of the Visual editor).

    So, how do I get TinyMCE to always initialize on its own and show the Visual Editor, in WordPress…? Without having to be clicked on to display it? I need the Visual Editor to be the very first “view” that a user sees of TinyMCE. Again — without the user having to to anything to get it to display.

    I’ve combed the ‘net looking for this answer for days. Forums, user groups, etc….and some say it’s a WordPress problem, others say it’s a problem with the TinyMCE itself. And the developers say it’s not a problem with their plugin….

    I suppose I need to find someone who knows both WordPress AND TinyMCE, lol….I’m so lost. SOOOO lost. Can anyone help? Who’s able to take this challenge on???? :) Man, I hope someone is able.

    Thanks in advance for any and all help. I sincerely appreciate it.

Leave a Reply

Use WordPress?

Use WordPress?

Join 20,000+ others who get our FREE weekly newsletter with WordPress tips on how to drive more traffic and revenue to your business!


You have Successfully Subscribed!

Send this to a friend