How to use WordPress 3.5 Media Uploader in Theme Options

December 13, 2012

WordPress 3.5 is just released with a number of major changes. The one I love most is HiDPI display support, WordPress looks so beautiful on my MacBook Pro Retina display. Besides, after the update was released I considered upgrading my StagFramework to the WordPress 3.5 standard, going ahead I implemented media uploader and color picker along with a couple of new functions in WP 3.5.

So as you all know that WordPress has got a new media uploader so why not to use it our theme options, WordPress theme developer would be happy working with this because it has got less hassle than previous media uploader; you don’t need to do any enqueue any script like we did before wp_enqueue_script('media-upload');. So let’s go ahead and see how can we achieve this.

I assume you have following code for uploader, that’s what I have used.

Once we have code above now let’s write some jQuery for upload button to work.

Bingo! We are done here. As you click on upload button you will see the new media uploader. If you want to play around the attachment, you can just do a console.log(attachment) or alert(attachment).

Meanwhile, if you come up with any better solution let me know in the comments.

Above code snippet works on post edit page only, to make it work elsewhere you need to use wp_enqueue_media(); in your theme. Thanks to daviedR for correcting me on this.

Author

Ram Ratan Maurya

75 Responses

  1. Hi Ram Ratan,

    Thanks for this small tutorial. I have done everything according to your tutorial, however an error occurs.

    Uncaught TypeError: Cannot read property ‘editor’ of undefined

    Can you help me with this?

  2. Hi, I got something like this,

    It missed a lot of scripts than yours. What registered scripts have you enqueued using wp_enqueue_script?

  3. No, I did it in my own option framework page. I tried to enqueue ‘plupload-handlers’ and now the source code has the exact line you wrote above. however it still goes to the same error, ‘wp’ variable on javascript doesn’t have ‘media’

  4. It turns out I need to call wp_enqueue_media() function in my functions.php. Otherwise it won’t work. Thanks Ram!

  5. I just checked it never worked on theme options page, with code in the article it will only work while editing the post. wp_enqueue_media(); does the trick for theme options page. Thanks for this one, will update the article shortly.

  6. Hi!

    I’m trying it on a custom options page and i’ve loaded the wp_enqueue_media(); but the media still won’t open.. am i missing something?

  7. Well, got it working now! I used another script which was working only on edit post screens but with the same one here it works on custom pages as well.

  8. Note that this method has one pitfall(when used on edit screens mainly) – since you restore the original handler for “wp.media.editor.send.attachment” after you send the first attachment, you will have a bug in the following situation:

    – User clicks on the button to open media
    – The user then decides that he’s not going to insert an image to your option and closes the media pop-up without choosing any media
    – The user then proceeds to add an image to their post content from the media pop-up
    – He selects the image, changes the settings, clicks the button and your option gets the image
    – User is confused and sad :(

    :)) In order to get around this, I’m trying to hook to the “close” event for the media pop-up(I know there’s got to be a way, I’ve been banging my head with it and haven’t found it yet though). Then you can set a flag variable(like “custom_media”) in your code – when the user clicks on your button, you set the variable to true. In the overriding function you check whether the flag variable is true – if it is, you execute your code, otherwise you execute the original code.

    Like I said the only problem is to find how exactly to hook to the close event… If you have any ideas, I’d love to hear them :)

  9. Hey Ram,

    I’ve been poking around and I finally found a simple enough(and I think safe enough) way to do this. I went from doing all kinds of ugly things(including overriding jQuery’s hide() function in order to intercept the hiding of the media pop-up), but at the end, I just bound a handler for click events on the Add Media button. Here’s a sample code(it’s not exactly the one I use, since it’s adapted to my situation, but it should still work):

    jQuery(document).ready(function($){

    var _custom_media = false,

    _orig_send_attachment = wp.media.editor.send.attachment;

    wp.media.editor.send.attachment = function(props, attachment){

    if ( _custom_media ) {

    $("#"+id).val(attachment.url);

    } else {

    return _orig_send_attachment.apply( this, [props, attachment] );

    };

    }

    $('.uploader .button').click(function(e) {

    var send_attachment_bkp = wp.media.editor.send.attachment;

    var button = $(this);

    var id = button.attr('id').replace('_button', '');

    wp.media.editor.open(button);

    return false;

    });

    $('.add_media').on('click', function(){

    _custom_media = false;

    })

    });

  10. PP: I have no clue why Disqus messed-up my code highlighting, but also it seems like I can’t actually delete my comment – instead it made it appear as a comment made from a Guest user :?

  11. How can I listen to the close event of the upload form. I like to trigger a custom function if no media is selected and the lightbox is just closed (with X, Escape or clicking outside)

  12. I just found a different way to make this work:
    var ed_id = $('.wp-media-buttons:eq(0) .add_media').attr( 'data-editor' ); // Get the proper editor id from the "Add Media" button
    var ed_media = wp.media.editor.get( ed_id ); // Try to get the editor instance
    ed_media = 'undefined' != typeof( ed_media ) ? ed_media : wp.media.editor.add( ed_id ); // If it doesn't exist, create it

    if ( ed_media ) { // If we have a media editor instance, we use it's "open" event
    ed_media.on('open', function(){
    _custom_media = false;
    });
    } else { // If we don't we hook to the "click" event for the "Add Media" button
    $('.add_media').on('click', function(){
    _custom_media = false;
    });
    };

    Props go to this article – http://wordpress.org/support/topic/new-media-manager-closeunload-event?replies=2

    Hope that helps :)

  13. Great. Thanks. I also wanted to edit the image and go to the Edit Gallery window. Do you know how to do that? Thanks again.

  14. Well, it’s possible. Just click on the image you want to edit, you’ll notice ‘Edit image’ in right sidebar, it will open a new tab. There you can edit your changes and after saving it just go back to previous tab and hit ‘Refresh’ in right sidebar and you’re all set.

  15. Thanks. That post doesn’t have the edit gallery option. Its about customizing the add media popup (removing other frames). And, its not about individual edit image. I want to behave it like the default Add Media and Edit Gallery buttons.. So, I can click Add Media and upload images, then also click on an ‘edit’ button to get the Edit Gallery window, the one you get when you have a gallery in the post and click Edit on that. I have been looking all over the place but can’t seem to find what triggers it. If you have any idea, please do reply. I will be hunting until then. :)

  16. Thanks for the code.

    I did this for my theme’s options page.

    jQuery(document).ready(function()
    {
    jQuery(‘#mp_logo_image_button’).click(function()
    {
    wp.media.editor.send.attachment = function(props, attachment)
    {
    jQuery(‘#mp_logo_image’).val(attachment.url);
    }

    wp.media.editor.open(this);

    return false;
    });
    });

    Seems to work fine. Sorry if the code above looks messy. How do you insert it nicely in the Disqus comments?

  17. Trying putting these codes in my theme option, not a success even with wp_enqueue_media().

    BTW where does .stag-metabox-table or .add_media come from?

  18. This is the error from my console:
    Uncaught TypeError: Cannot read property ‘id’ of undefined (load-scripts.php:69)
    Uncaught TypeError: Cannot read property ‘send’ of undefined (themes.php:39)

  19. .stag-metabox-table is the name the button’s class which initiates the uploader. And the property ‘id’ is just an attribute of the same. Your question’s answer relies in the code snippet itself.

  20. Thanks, what about .add_media ? I ask because didn’t see them in the html example that you provide. I just placed your code in my functions.php and changed ‘_unique_name’

  21. Sorry for the delay @twitter-15857957:disqus I didn’t notice your comment. You can put the code in .js file and enqueue it in admin using admin_enqueue_scripts. Refer to WordPress Codex for more info.

  22. I’ve been trying for a while now to add the new wordpress 3.5 uploader to a plugin I am developing. Problem is there is little information out there about it, your post being one of the few helpful posts on the matter. I’ve been trying to use the wp_enqueue_scripts() function to add the necessary scripts to my admin page. However, doing this is breaking my page for some reason. I have also tried using the admin_enqueue_scripts to load the scripts but it keeps breaking simply saying that there is a server error configuration. I was wondering if you could give me some guidance on how to go about using the wp_enqueue_scripts() function?

  23. Hey Roberto Damery,

    Firstly, wp_enqueue_scripts is not a function, it’s an action hook. Correct function is wp_enqueue_script(). Since you need to display scripts in admin you must use admin_enqueue_scripts action hook.

    As per the error, there must be something wrong with your code. In this case, you should try debugging your code.

    Besides, you should read more about enqueuing the scripts in WordPress: http://codex.wordpress.org/Function_Reference/wp_enqueue_script

  24. Hmmm for some reason i can’t get it work. I’m using WP 3.5.1 and i don’t think that i am missing anything. js script is enqueued, input is there, all classes are properly (re)named. Can you check if you got time if it’s working in 3.5.1? Thanks

  25. Yes it works for me. I’m using the same (more customised and complicated) code for all of my projects.

    Check for any errors in console. And make sure you have wp_enqueue_media(); in your code.

  26. I was looking for a similar and more customizable solution and came across the demo posted by the author of the WP Media Uploader – Dominik Schilling

    https://github.com/ocean90/media-modal-demo.

    Great tutorials that show how you can customize the button text, title and the media upload manager.

  27. I am implementing this on the front end. However, I keep getting this error:

    Uncaught TypeError: Cannot read property ‘editor’ of undefined

    It looks like the wp.editor class is defined in media-models.js, but wp_enqueue_media() does not load this file. So I loaded it manually, but it seems to require variables that get set by other files that also don’t get loaded. Do you know of a way to make wp_enqueue_media() to actually load all the scripts it needs to load?

  28. I just tested the code at my end in a blank theme and it works perfectly for me, I was able to get the media dialog open. There must be something going wrong there, try inspecting a little more. I could look into the issue if you have this site online somewhere.

  29. It’s on localhost.
    wp_enqueue_media() is loading the following scripts: utils.min.js, plupload.js, plupload.html5.js, plupload.flash.js, plupload.silverlight.js, plupload.html4.js, json2.min.js. And that’s it. Does yours load additional scripts automatically?
    I will try this from a fresh installation, as I had run into another problem, too, in that enqueue_script(‘heartbeat’) was not loading heartbeat.js, either. I’ll come back here and share any solution I find.

  30. I have discovered the problem. I had not yet called wp_footer() in the page template I was working on. wp_enqueue_media loads most of its scripts in the footer, so that is why they were not getting loaded.
    Thank you for the great tutorial.

  31. where do you put wp_enqueue_media??? i’m tryin to put a upload fom on the category edit screen thx

  32. i apply the setps below, but i can’t use it when i click on Upload! how to slove it?
    and i don’t understand wp_enqueue_media(); how to use it ? please if you cloud explain it with example..
    thanks

  33. Great stuff! Thanks! This was very helpful … I was able to adapt this code to work with the WP Types plugin — a great plugin but one that still uses the old thickbox dialog for custom image fields.

  34. If this never work on theme option page, you should change this article title to something else…just sayin..

  35. Thanks, worked like a charm! I also added this bit of js and it will force the tab to be selected on The upload tab instead of the media library :)

    wp.media.controller.Library.prototype.defaults.contentUserSetting=false;

  36. I don’t know why, bu “Upload files” button won’t work on frontend page. Media library opens, I can select uploaded media, but can’t upload a new one. Any ideas?
    Thanks in advance!

  37. How would I get the option to choose external image url like when adding inline images to the page/post content?

    Trying to add this feature to an Ad space widget I’m working on.

    Thanks for any help!

  38. But that’s a different method, is there any way to do that with your method?

  39. Both the code snippets can be easily merged together by making some minor changes. Your best bet would be explore the wp.media in order to get deep with that.

  40. hi Ratan thz for this tutorial but i have a quastion, im trying to save image with

    if( isset( $_POST[ ‘attachment’ ] ) ) {
    update_post_meta( $servicos_id, ‘attachment’, $_POST[ ‘attachment’ ] );
    }

    but when i update the vale on sql still empty and lost the value of the url attachment. How can i do it ?