Open/Access WP Media library from tinymce plugin popup window Open/Access WP Media library from tinymce plugin popup window wordpress wordpress

Open/Access WP Media library from tinymce plugin popup window


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 abovetinymce.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 :)


I took the code of Paolo and simplified it in order not to have many files to manage. Also, I didn't manage to make it work like this.

So this solution has less code and uses only one single file.

Just put this in your tinyMCE plugins js file:

(function(){    tinymce.PluginManager.add('myCustomButtons', function(editor, url){        editor.addButton('btnMedia', {            icon: 'image',            tooltip: 'Add an image',            onclick: function() {                editor.windowManager.open({                    title: 'Add an image',                    body: [{                        type: 'textbox',                        subtype: 'hidden',                        name: 'id',                        id: 'hiddenID'                    },                    {                        type: 'textbox',                        name: 'text',                        label: 'Text',                        id: 'imageText'                    },                    {                        type: 'button',                        text: 'Choose an image',                        onclick: function(e){                            e.preventDefault();                            var hidden = jQuery('#hiddenID');                            var texte = jQuery('#imageText');                            var custom_uploader = wp.media.frames.file_frame = wp.media({                                title: 'Choose an image',                                button: {text: 'Add an image'},                                multiple: false                            });                            custom_uploader.on('select', function() {                                var attachment = custom_uploader.state().get('selection').first().toJSON();                                hidden.val(attachment.id);                                if(!texte.val()){                                    if(attachment.alt)                                        texte.val(attachment.alt);                                    else if(attachment.title)                                        texte.val(attachment.title);                                    else                                        texte.val('See the image');                                }                            });                            custom_uploader.open();                        }                    }],                    onsubmit: function(e){                        var image = '<button data-id="'+e.data.id+'">'+e.data.text+'</button>';                        editor.insertContent(image);                    }                });            }        });    });})();

The result in the frontend html is a button which has the ID of the image in a data-id attribute, and a text to display (the alt of the image, by default, or its title or a text the user can write).

Then, with my frontend js, I will get the corresponding image with its ID and show it in an ajax popup.

With this solution, you have all of your js functions in one single file, and you don't need to enqueue any script nor to create a php file.


I know it's old but in case anyone else facing the same situation, The Paolo's solution above is working fine but no need to enqueue wp_enqueue_media(); this will load a bunch of scripts, you can load only 2 scripts:

wp_enqueue_script( 'jquery' );wp_enqueue_script( 'media-lib-uploader-js' );