TinyMCE popup add media button

Inside a WordPress theme I am developing, i’ve a TinyMCEPopup to add shortcode to the editor, some shortcode requires images. Can i add an “Add media” button which opens the WordPress media uploader and allow the user to select or upload an image even if i’m inside a TinyMCEPopup?

Related posts

Leave a Reply

2 comments

  1. Don’t know if it will help, but I had the same issue and solved it like this.

    In functions.php add

    add_action( 'after_setup_theme', 'mytheme_theme_setup' );
    
    if ( ! function_exists( 'mytheme_theme_setup' ) ) {
        function mytheme_theme_setup() {
    
            add_action( 'init', 'mytheme_buttons' );
    
        }
    }
    
    /********* TinyMCE Buttons ***********/
    if ( ! function_exists( 'mytheme_buttons' ) ) {
        function mytheme_buttons() {
            if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
                return;
            }
    
            if ( get_user_option( 'rich_editing' ) !== 'true' ) {
                return;
            }
    
            add_filter( 'mce_external_plugins', 'mytheme_add_buttons' );
            add_filter( 'mce_buttons', 'mytheme_register_buttons' );
        }
    }
    
    if ( ! function_exists( 'mytheme_add_buttons' ) ) {
        function mytheme_add_buttons( $plugin_array ) {
            $plugin_array['mybutton'] = get_template_directory_uri().'/js/tinymce_buttons.js';
            return $plugin_array;
        }
    }
    
    if ( ! function_exists( 'mytheme_register_buttons' ) ) {
        function mytheme_register_buttons( $buttons ) {
            array_push( $buttons, 'mybutton' );
            return $buttons;
        }
    }
    

    This will initialize the button you need. Now in the tinymce_buttons.js you’ll add something like

    (function() {
        tinymce.PluginManager.add('mybutton', function( editor, url ) {
            editor.addButton( 'mybutton', {
                text: 'My button for media upload',
                icon: false,
                onclick: function() {
                    editor.windowManager.open( {
                        title: 'Insert Media',
                        body: [
                            {
                                type: 'textbox',
                                name: 'img',
                                label: 'Image',
                                value: '',
                                classes: 'my_input_image',
                            },
                            {
                                type: 'button',
                                name: 'my_upload_button',
                                label: '',
                                text: 'Upload image',
                                classes: 'my_upload_button',
                            },
                        ],
                        onsubmit: function( e ) {
                            editor.insertContent( '[shortcode-name img="' + e.data.img + '"]');
                        }
                    });
                },
            });
        });
    
    })();
    
    jQuery(document).ready(function($){
        $(document).on('click', '.mce-my_upload_button', upload_image_tinymce);
    
        function upload_image_tinymce(e) {
            e.preventDefault();
            var $input_field = $('.mce-my_input_image');
            var custom_uploader = wp.media.frames.file_frame = wp.media({
                title: 'Add Image',
                button: {
                    text: 'Add Image'
                },
                multiple: false
            });
            custom_uploader.on('select', function() {
                var attachment = custom_uploader.state().get('selection').first().toJSON();
                $input_field.val(attachment.url);
            });
            custom_uploader.open();
        }
    });
    

    First you add the button functionality. The list of options to put in popup is given here. It’s not 100% complete, but better than the official documentation which is crap.

    The first part is the button initialization. This gives you a ‘My button for media upload’ button, and on click you should get a modal with input field and a button.

    On button click the media upload will open and you can select your image. On select the url will be in the input field, and you’ll get it in your shortcode.

    Hope it helps 🙂

  2. There was another question like this (Open/Access WP Media library from tinymce plugin popup window) , so I’m pasting my answer here since this is similar:

    Hi – I had the same problem just now and found the solution so I’m sharing it here. I hope it’s not too late.

    First to be able to use WP Add Media button you would have to enqueue the needed script. This is easy, just call the wp_enqueue_media() function like so:

    add_action('admin_enqueue_scripts', 'enqueue_scripts_styles_admin');
    function enqueue_scripts_styles_admin(){
        wp_enqueue_media();
    }
    

    This call ensures you have the needed libraries to use the WP Media button.

    Of course you should also have the HTML elements to hold the uploaded/selected media file URL, something like this:

    <input type="text" class="selected_image" />
    <input type="button" class="upload_image_button" value="Upload Image">
    

    The first text field will hold the URL of the media file while the second is a button to open the media popup window itself.

    Then in your jscript, you’d have something like this:

        var custom_uploader;
    
        $('.upload_image_button').click(function(e) {
            e.preventDefault();
    
            var $upload_button = $(this);
    
            //Extend the wp.media object
            custom_uploader = wp.media.frames.file_frame = wp.media({
                title: 'Choose Image',
                button: {
                    text: 'Choose Image'
                },
                multiple: false
            });
    
            //When a file is selected, grab the URL and set it as the text field's value
            custom_uploader.on('select', function() {
                var attachment = custom_uploader.state().get('selection').first().toJSON();
                $upload_button.siblings('input[type="text"]').val(attachment.url);
            });
    
            //Open the uploader dialog
            custom_uploader.open();
    
        });
    

    Now I’m not going to explain every line because it’s not that hard to understand. The most important part is the one that uses the wp object to make all these to work.

    The tricky part is making all these work on a TinyMCE popup(which is the problem I faced). I’ve searched hi and lo for the solution and here’s what worked for me. But before that, I’ll talk about what problem I encountered first. When I first tried to implement this, I encountered the “WP is undefined” problem on the popup itself. To solve this, you just have to pass the WP object to the script like so:

    (function() {
    tinymce.create('tinymce.plugins.someplugin', {
        init : function(ed, url) {
            // Register commands
            ed.addCommand('mcebutton', function() {
                ed.windowManager.open(
                    {
                        file : url + '/editor_button.php', // file that contains HTML for our modal window
                        width : 800 + parseInt(ed.getLang('button.delta_width', 0)), // size of our window
                        height : 600 + parseInt(ed.getLang('button.delta_height', 0)), // size of our window
                        inline : 1
                    },
                    {
                        plugin_url : url,
                        wp: wp
                    }
                );
            });
    
            // Register buttons
            ed.addButton('someplugin_button', {title : 'Insert Seomthing', cmd : 'mcebutton', image: url + '/images/some_button.gif' });
        }
    });
    
    // Register plugin
    // first parameter is the button ID and must match ID elsewhere
    // second parameter must match the first parameter of the tinymce.create() function above
    tinymce.PluginManager.add('someplugin_button', tinymce.plugins.someplugin);
    
    })();
    

    What we’re interested in is this line => “wp: wp” . This line ensures that we are passing the wp object to the popup window (an iframe really…) that is to be opened when we click the tinymce button. You can actually pass anything to the popup window via this object (the 2nd parameter of the ed.windowManager.open method)!

    Last but not the least you’d have to reference that passed wp object on your javascript like so:

        var args = top.tinymce.activeEditor.windowManager.getParams();
        var wp = args.wp;
    

    Make sure you do that before calling/using the WP object.

    That’s all you have to do to make this work. It worked for me, I hope it works for you 🙂