How is it possible to add a custom button to the visual editor TinyMCE, Version 4?

Currently I found this q&a with a little bit hints to the topic, but not a solution or a how to. But I can't find a tutorial, documentation, q&a for the topic to add a custom button to the TinyMCE version 4, include in WordPress since version 3.9-beta1.


enter image description here

3 Answers 3


The following small plugin creates a custom button inside line 1 of the WordPress TinyMCE Version 4, tested in WP Version 3.9-beta2.

The plugin has var_dump included to understand the values. It's also possible to add the button to other lines of the visual editor, only a other hook, like for line 2: mce_buttons_2.


enter image description here

Plugin, PHP side - tinymce4-test.php

 * Plugin Name: TinyMCE 4 @ WP Test
 * Description: 
 * Plugin URI:  
 * Version:     0.0.1
 * Author:      Frank Bültge
 * Author URI:  http://bueltge.de
 * License:     GPLv2
 * License URI: ./assets/license.txt
 * Text Domain: 
 * Domain Path: /languages
 * Network:     false

add_action( 'admin_head', 'fb_add_tinymce' );
function fb_add_tinymce() {
    global $typenow;

    // Only on Post Type: post and page
    if( ! in_array( $typenow, array( 'post', 'page' ) ) )
        return ;

    add_filter( 'mce_external_plugins', 'fb_add_tinymce_plugin' );
    // Add to line 1 form WP TinyMCE
    add_filter( 'mce_buttons', 'fb_add_tinymce_button' );

// Inlcude the JS for TinyMCE
function fb_add_tinymce_plugin( $plugin_array ) {

    $plugin_array['fb_test'] = plugins_url( '/plugin.js', __FILE__ );
    // Print all plugin JS path
    var_dump( $plugin_array );
    return $plugin_array;

// Add the button key for address via JS
function fb_add_tinymce_button( $buttons ) {

    array_push( $buttons, 'fb_test_button_key' );
    // Print all buttons
    var_dump( $buttons );
    return $buttons;

Script, JavaScript side - plugin.js

( function() {
    tinymce.PluginManager.add( 'fb_test', function( editor, url ) {

        // Add a button that opens a window
        editor.addButton( 'fb_test_button_key', {

            text: 'FB Test Button',
            icon: false,
            onclick: function() {
                // Open window
                editor.windowManager.open( {
                    title: 'Example plugin',
                    body: [{
                        type: 'textbox',
                        name: 'title',
                        label: 'Title'
                    onsubmit: function( e ) {
                        // Insert content when the window form is submitted
                        editor.insertContent( 'Title: ' + e.data.title );

                } );

        } );

    } );

} )();


Use the Gist bueltge/9758082 as reference, or download. The Gist also has more examples for different buttons in TinyMCE.


  • 2
    The TinyMCE documentation on how to create dialog isn't actually very helpful. So I went ahead and wrote an article listing the different widgets and containers layout available: makina-corpus.com/blog/metier/2016/…
    – Gagaro
    Commented Mar 30, 2016 at 9:31

And, if you'd like to have an actual icon button, then you can leverage dashicons, or your own icon font for it.

Create a CSS file, and enqueue on the admin side;

i.mce-i-pluginname:before {
    content: "\f164";
    display: inline-block;
    -webkit-font-smoothing: antialiased;
    text-align: center;
    font: 400 20px/1 dashicons!important;
    speak: none;
    vertical-align: top;

Basically taken straight from core.

  • Right, was inside my Links above in the Links-list.
    – bueltge
    Commented Mar 27, 2014 at 9:02
  • Wish I had found this answer before spending half an hour trying to add it via a CSS file. This seems like the best way to do it; all the tutorials I've found online are unnecessarily verbose.
    – aendra
    Commented Jul 14, 2014 at 9:24

The simple method of adding button


add_action('admin_init', 'add_cb_button');function add_cb_button() {
   if (current_user_can('edit_posts')  &&  get_user_option('rich_editing') == 'true') {
        add_filter('mce_buttons_2', 'register_buttonfirst');
        add_filter('mce_external_plugins', 'add_pluginfirst');
function register_buttonfirst($buttons) {  array_push($buttons, "|", "shortcode_button1" );   return $buttons;}
function add_pluginfirst($plugin_array) {$plugin_array['MyPuginButtonTag'] =  plugin_dir_url( __FILE__ ).'My_js_folder/1_button.php';return $plugin_array;}
add_filter( 'tiny_mce_version', 'my_refresh_mceeee1');  function my_refresh_mceeee1($ver) {$ver += 3;return $ver;}

2) Create 1_button.php in target folder and insert this code (note, change "wp-load" and "ButtonImage.png" urls!!!)

header("Content-type: application/x-javascript");
(function() {
    // START my customs
    var abcd =location.host;

    tinymce.create('tinymce.plugins.shortcodebuton_plugin2', {  
        init            : function(ed, this_folder_url)
                    // -------------------------
                    ed.addButton('shortcode_button1', {  
                        title : 'Show Level1 count',  
                        image : this_folder_url + '/ButtonImage.png',
                        onclick : function() {  
                                //var vidId = prompt("YouTube Video", "");
                                //ed.execCommand('mceInsertContent', false, '[youtube id="'+vidId+'"]');


        createControl   : function(n, cm) {     return null;  }, 
    tinymce.PluginManager.add('MyPuginButtonTag', tinymce.plugins.shortcodebuton_plugin2);  
  • I think this not the best way. The include of the wp-load.php is not stable. The pace, where leave this file is different. The install of WordPress have default possibilities to move the theme and plugin folder.
    – bueltge
    Commented Feb 20, 2015 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.