Add a custom TinyMCE button with image upload option in the WordPress WYSIWYG editor

Can I add an image upload or image select option to a custom TinyMCE button in the WordPress WYSIWYG editor?

Yes, you can create a custom button in the WYSIWYG editor, and after clicking that button, it will open a dialog or modal popup where you can add a custom image field. After selecting an image, you will insert the image URL into the HTML content.

Custom TinyMCE Button

In the example code below, I will explain how to add custom text and an image to a custom button in the WYSIWYG visual editor.

1. Add this code in function.php file (Custom TinyMCE Plugin)

You'll need to enqueue a JavaScript file where you can add custom TinyMCE configurations. Add the following code to your theme's functions.php file:

// mce buttons for wysiwyg editor
function custom_tinymce_plugin( $plugin_array ) {
  $plugin_array['custom_mce_button'] = get_template_directory_uri() .'/js/custom_tinymce_button.js';
  return $plugin_array;
}
add_filter( 'mce_external_plugins', 'custom_tinymce_plugin' );

This function loads a custom JavaScript file that adds functionality to the TinyMCE editor.

// Register mce buttons in wysiwyg
function register_mce_buttons( $buttons ) {
  array_push( $buttons, 'custom_mce_button' );
  return $buttons;
}
add_filter( 'mce_buttons', 'register_mce_buttons' );

This function registers a new button in the TinyMCE editor toolbar.

2. Add this code to your JS file. (Register TinyMCE Buttons)

Create a JavaScript file named custom_tinymce_button.js in your theme's js directory and add the following code.
(function($) {    
	tinymce.PluginManager.add('custom_mce_button', function(editor, url) {
        editor.addButton('custom_mce_button', {
            text: 'Custom Button',
            icon: false,
            onclick: function() {
                var thumbnailImageFrame;
                var thumbnailImageURL = '', thumbnailImageAlt = '';

                var win = editor.windowManager.open({
                    title: 'Select Image and Heading',
                    body: [
                        {
                            type: 'button',
                            name: 'thumbnail_image',
                            label: 'Select Thumbnail Image',
                            text: 'Select Thumbnail Image',
                            classes: 'overflow-hidden',  // Add custom class
                            onclick: function() {
                                if (thumbnailImageFrame) {
                                    thumbnailImageFrame.open();
                                    return;
                                }
                                thumbnailImageFrame = wp.media({
                                    title: 'Select or Upload Thumbnail Image',
                                    button: {
                                        text: 'Use this image'
                                    },
                                    multiple: false
                                });

                                thumbnailImageFrame.on('select', function() {
                                    var attachment = thumbnailImageFrame.state().get('selection').first().toJSON();
                                    thumbnailImageURL = attachment.url;
                                    thumbnailImageAlt = attachment.alt;
                                    win.find('#thumbnail_image_url_display').text(attachment.url);
                                    win.find('#thumbnail_image_alt_display').text(attachment.alt);

                                    // Update button text to image name
                                    win.find('button[name=thumbnail_image]').text(attachment.filename);
                                });

                                thumbnailImageFrame.open();
                            }
                        },
                        {
                            type: 'container',
                            html: '<div id="thumbnail_image_url_display"></div><div id="thumbnail_image_alt_display"></div>'
                        },
                         {
                            type: 'textbox',
                            name: 'heading',
                            label: 'Heading',
                            value: ''
                        }
                    ],
                    onsubmit: function(e) {
                        if (thumbnailImageURL) {
                            editor.insertContent(`<h2>`+e.data.heading+`</h2><img alt="${thumbnailImageAlt}" src="${thumbnailImageURL}"/>`);
                        }
                    }
                });
            }
        });
    });
})(jQuery);

This code is a custom TinyMCE plugin written in JavaScript that adds a button to the WordPress WYSIWYG editor (TinyMCE). When clicked, this button opens a modal window that allows the user to select an image from the WordPress media library and enter a heading. The selected image and heading are then inserted into the editor content.

Thank You!