Using the WordPress Uploader in Your Plugin or Theme
January 8th, 2010 by MattWordPress has a nice media uploader dialog that it uses on the editor pages. Now wouldn’t it be nice if you could use it to handle image uploads for part of a plugin or theme you’re writing? Maybe you want to add an easy way to change the logo in a theme? A simple “Upload Image” button would work quite well for that, wouldn’t it?

It’s fairly simple to implement, providing you already have a bit of experience with the WordPress API.
The first step is to prepare your HTML. Put it wherever the code for your admin page is. You want to have a text input for the image URL, and a button that will launch the uploader dialog.
<tr valign="top"> <th scope="row">Upload Image</th> <td><label for="upload_image"> <input id="upload_image" type="text" size="36" name="upload_image" value="" /> <input id="upload_image_button" type="button" value="Upload Image" /> <br />Enter an URL or upload an image for the banner. </label></td> </tr>
Now that the easy part is out of the way, it’s time to start making it do something. You need to enqueue some scripts and styles. Here’s an example function to show how it’s done:
function my_admin_scripts() {
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
wp_register_script('my-upload', WP_PLUGIN_URL.'/my-script.js', array('jquery','media-upload','thickbox'));
wp_enqueue_script('my-upload');
}
function my_admin_styles() {
wp_enqueue_style('thickbox');
}
if (isset($_GET['page']) && $_GET['page'] == 'my_plugin_page') {
add_action('admin_print_scripts', 'my_admin_scripts');
add_action('admin_print_styles', 'my_admin_styles');
}
We need the media-upload and thickbox scripts for starters, as well as jQuery, which is already included. Then we have to register and enqueue our own JavaScript file, my-script.js, which will handle the media uploader functionality. We also need to load the thickbox stylesheet in the next function.
The if (…) block ensures that the scripts and styles will only be included if the user is on a specific admin page. If you look at your plugin’s (or theme’s) admin page, the URL should have a ?page=some_string at the end. Substitute my_plugin_page for that string.
Now for the part the actually invokes the uploader: the JavaScript. This will go in the my-script.js file we included earlier.
jQuery(document).ready(function() {
jQuery('#upload_image_button').click(function() {
formfield = jQuery('#upload_image').attr('name');
tb_show('', 'media-upload.php?type=image&TB_iframe=true');
return false;
});
window.send_to_editor = function(html) {
imgurl = jQuery('img',html).attr('src');
jQuery('#upload_image').val(imgurl);
tb_remove();
}
});
The first click() event listener opens a ThickBox dialog when the “Upload Image” button is clicked, and loads the uploader page inside it. It also stores the name of the URL input field in a variable, for later use.
The second function overrides the send_to_editor() function in the media-upload script. This is probably the most important part. When the “Insert into Post” button is clicked in the uploader dialog, this function fires. It collects the URL of the image that was uploaded, dumps it into the awaiting form field, and closes the ThickBox dialog.
That’s it. Providing everything went according to planned, you should have a form field that will either accept an arbitrary image URL, or allow a user to upload one on the spot.

Very cool – It looks like Wordpress theme creators are spending more and more time on the details, and of course the ability to easily swap out the logo in a theme is a great little feature.
Don’t forget plugin creators! I put this post together because I was working on a plugin. I figured out how to do it by studying a couple of plugins that had upload features.
May have to test drive this into my Custom Login theme.
Thanks for the article. It really got me thinking
May sound like a stupid request, but could you provide a ‘generic’ plugin with nothing more than the input box in the admin page, along with the way I would call that image in my template?
I was thinking of trying this idea to allow my user to upload the background image for their theme as a starter, and if I can see how that works, then I’m pretty sure I can hack the code to use it in other places.
I don’t really want to be maintaining another plugin at this point.
However, the code I provided above is fairly nonspecific, and should be possible to fit into any application, giving some work. It would require some PHP/WordPress experience though.
However, if you’re looking for a quicker solution, you might try looking at existing themes or plugins with uploader capabilities. I think Kubrick, the default WP theme, might have a similar uploader (?) to allow users to add a background image to the header. I may not be remembering correctly about Kubrick, but I know there are several themes that offer functionality along those lines. I should be trivial to borrow some code from the themes and insert it into your functions.php.
Wow, that’s great. Thank you! Will use it for a Client Website, so he can change the Logo easily.
I managed to get this working on my site, but I have one quick question if you don’t mind.
How do I change it from a single image selection to an array of selections?
Meaning, my theme has a logo, page background, and a footer background. I would like to have a page with 3 uploaders so that the user can select an image for each field.
I tried replicated the code 3x on the same page, but that just threw up a ton of errors.
Another reader worked out a way to have multiple uploaders: http://www.theenglishguy.co.uk.....tions-php/
Just make sure you give the input tags different name and id attributes.
How do I automatically upload multiple images selecting multiple images with uploader?. Colud I, for example, fill a list box with all images uploaded through uploader?. I mean I don’t want to use multiple uploaders as the post you have shown.
If you wanted to populate some other type of form field with more than one URL, you could, but you would have to figure out your own script. You would need to use jQuery to append instead of replace the form text.
Or to use the add_attachment filter. I managed to automatically add the ID of each image uploaded to my own database. Thanks.
This is so great . I was looking for that
How can I use it in Theme option or custom meta box in post ?
hope to found the answer .
Thanks alot
Sub
You can use it wherever you want, providing you queue-up the requisite scripts. So, yes, it would work fine in either a meta box or an options page.
Awsome thanks! With these guidelines I could quite easily implement this.
First I tried getting some other jquery uploader and image crop tool working, but when the WP supplied tools work – and is easily implementable like you guided – then imho its clearly best to use them.
How can this be done with a custom meta box and not screw up the regular media uploader? Right not it will automatically pull anything you try to use in the post even if your not trying ot use the custom meta box/field.
It should depend on what ids you use for the form and script.
Mind providing an example that would work? I basically just used your example, which didnt as it obviously conflicted like i mentioned before. Thanks for the help. I appreciate it.
I looked over the code again, and I think your problem might be because the script overrides the window.send_to_editor function from the uploader. My JS skills aren’t really sufficient to prescribe a solution for your scenario, but you might want to look into something like this:
http://stackoverflow.com/quest.....e-original
I’ve come up with this code to allow for the original send to editor to work.
jQuery(document).ready(function() {
var formfield;
jQuery(‘#Image_button’).click(function() {
jQuery(‘html’).addClass(‘Image’);
formfield = jQuery(‘#Image’).attr(‘name’);
tb_show(”, ‘media-upload.php?type=image&TB_iframe=true’);
return false;
});
/*
window.send_to_editor = function(html) {
if ( jQuery(‘html’).hasClass(‘Image’) ) {
imgurl = jQuery(‘img’,html).attr(’src’);
jQuery(‘#Image’).val(imgurl);
tb_remove();
jQuery(‘html’).removeClass(‘Image’);
}
}*/
// user inserts file into post. only run custom if user started process using the above process
// window.send_to_editor(html) is how wp would normally handle the received data
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor = function(html){
if (formfield) {
fileurl = jQuery(‘img’,html).attr(’src’);
jQuery(‘#Image’).val(fileurl);
tb_remove();
jQuery(‘html’).removeClass(‘Image’);
} else {
window.original_send_to_editor(html);
}
};
});
Which I modified from the code snippet
Matt!!!
Thank you very much, dude. Your tips was extremely helpful for me to implement my “featured” plugin. I searched all over the internet for this, and thanks Godgle I found your post.
Now my little plugin is just rocking.
Thanks again!
Saved me a lot of work. Thanks!!!!!!
Great tutorial, works perfectly.
Is there a way to use this for other media types (specifically PDF)? I understand everything but the javascript, and can’t seem to pinpoint what to change in there.
Thanks again for great tutorial.
Okay, I finally figured it out, and everything seems to work this way.
I changed this line:
imgurl = jQuery(‘img’,html).attr(’src’);
to this:
imgurl = jQuery(html).attr(‘href’);
Works as far as I can tell.
Thanks Kirk
just what i needed!
and Matt great post, works really well.
It’s a great way to integrate WP upload box to my plugin. Thanks for sharing.
do not work under 2.9.2?
it seems that the send_to_editor function has never been called…
hi!
thanks for your great article.
i wondering how hard to search the web for wordpress references, google always give me irrelevant results.
for example, i want to know which kind of types are allowed:
“media-upload.php?type=”
maybe i can see through bunch of php codes, but it could be great, if the media library documented.
can you help me with a link to this?
Hey,
Any way this can be used for a front-end custom post form?
Thanks
Probably, but I wouldn’t recommend it. Front-end uploaders need additional security checks. You need to verify that the item being uploaded is the type of file you expect (and simply checking for a .jpg or .png extension isn’t enough). Otherwise someone could upload what amounts to malware.
So all files keep in wp-content/uploads folder?
how to change it?
regards
thanks
Hi Matt, Thanks you very much for sharing this script, you are a GOD sent for me.
Copied your code and added it to Datafeedr Random Ad V2 where I would like to add an upload image option instead of pasting the image as html. Somehow the upload button does not invoke anything at all. Would that be because of the way I adjusted the function:
function my_admin_scripts() { // load necessary script including new script
wp_enqueue_script(‘media-upload’);
wp_enqueue_script(‘thickbox’);
wp_register_script(‘my-upload’, get_bloginfo(‘wpurl’) .’/wp-content/plugins/datafeedr-ads/my-script.js’, array(‘jquery’,'media-upload’,'thickbox’));
wp_enqueue_script(‘my-upload’);
}
and the fact that I added the code later on in the script?
You have the add_action() hooks calling the function, right? I don’t see anything jumping out at me that would cause it to fail…
I use these actions:
if (isset($_GET['page']) && $_GET['page'] == ‘datafeedr-ads’) {
add_action(‘admin_print_scripts’, ‘my_admin_scripts’);
add_action(‘admin_print_styles’, ‘my_admin_styles’);
}
Maybe the page datafeedr-ads should be added differently in the first line?
Been using this successfully on a plugin I’ve written, but when testing on WordPress 3.0 beta 2, I’m not actually getting an “Insert into Post” button on the media uploader.
Anyone else having the same problem?
@ Owen Been trying to add it to datafeedr random adds without any luck: http://wordpress.pastebin.com/yprywP7J Any ideas what I am missing? I would really appreciate your insight..
This is a great article! It works perfectly on my plug-in.
I’m wondering if its possible to implement Amazon S3 on this?. any ideas?
thanks,
I don’t know. There are some plugins that somehow commandeer the uploader and send the files to S3, I believe. You might take a look at their code, if I you can find one.
I suppose one way would be to temporarily upload the file and have the callback pass the file path to a script that copies it to S3 and then deletes it from the local server (returning the new S3 URL, of course).
Great tutorial. but i one problem my form field doesn’t accept an arbitrary image URL.
I think line 11 doesn’t assign the value(imgurl) on the id (#upload_image). any idea what am i missing?
09 window.send_to_editor = function(html) {
10 imgurl = jQuery(‘img’,html).attr(’src’);
11 jQuery(‘#upload_image’).val(imgurl);
12 tb_remove();
13 }
Matt, how can i unsubscribe comments?
There should be a link in the emails.
Matt, I think it doesn’t work on the later versions of wordpress or am i just missing something? because I try the code above under wordpress 3.0 beta 2, it seems that the send_to_editor function has never been called.
any success on the latest version? thnx
I haven’t tested it on the 3.0 builds yet. I may give it a look when I have time. (The only place I’m using the code is in a plugin I’ve been working on, and I don’t want to upgrade the development environment until 3.0 goes gold.)
I’m also implementing this code on the plugin that im currently woring on, it works like a charm and i was able to upload the image but this code below doesn’t seem to work as expected.
window.send_to_editor = function(html){
imgurl = jQuery(“img”,html).attr(’src’);
jQuery(“#upload_image”).val(imgurl);
tb_remove();
}
Anyone else having the same problem?
you probably are missing your STYLESHEET file.
how can I define where the media should be uploaded to? Lets say I want to have it in images/abc/
bascically, I want the uploader to only upload to images/abc/
is that possible?
thanks
/aleto
I don’t know. I haven’t explored it that far yet. It’s probably possible.
How can I get the gallery tab to show up after uploading multiple images and then saving. With the regular editor when you click save it loads the gallery tab. I don’t have a textfield just an upload submit button.
Any help would be great. Thanks for the great tutorial.
MB
Or how can I get the post id into the “media-upload.php” line in the JavaScript?
original…
media-upload.php?type=image&TB_iframe=true
would like…
media-upload.php?post_id=$post->ID&type=image&TB_iframe=true
Really I would like to insert a gallery into a custom field. Can I do that?
Thanks again.
First up, cracking article. Thank you. However, on WordPress 3.0 there is a small problem as several people have pointed out above. When you upload an image you don’t get the ‘insert into post’ button to press. However, once you’ve uploaded an image, it’s in the ‘media library’ tab. So if you click on that and then press ’show’ next to the relevant image, you THEN get the option to insert into post.
So your code DOES work, however it’s not the most user-friendly at the moment. My javascript skills are somewhat limited (read as: pathetic), so I’m not sure how’d you fix this, but I can think of two possible options:
1) Override the ’save all changes’ button instead of the insert into post – because this button DOES show up, but the ‘insert into post’ button doesn’t
2) Add an ‘insert into post’ button next to the ’save all changes’ button manually using some jQuery magic.
Hopefully this feedback helps a little, I’d love to know if you come up with a way around this!
I’m not an expert at JavaScript voodoo either.
It might be fun to play around with this some more, but I’ve been busy to the point that I haven’t even managed to test my plugins on 3.0. (I haven’t upgraded any of my blogs yet, either.)
Just for reference I’ve opened up a thread on the WordPress.org forums:
http://wordpress.org/support/topic/412979
Hopefully someone with some javascript awesomesauce can sprinkle some magic dust and make this work
I found a solution, albeit a hack-ish one, for the absence of the inset into post button. Just comment out or delete line 1267, if ( $send ) in /wp-admin/includes/media.php
As I said, it’s a hack and updates will likely overwrite the change, but it works. This functionality is important in the site I am currently building, so I will keep digging for a better solution.
An absolute ninja friend of mine who is wise in the ways of javascript (amongst many other disciplines) has hacked and scratched away and has come up with this as a replacement for your script.js file:
http://pastebin.com/tpwsY1iu
This ONLY works for the html uploader – i.e. it doesn’t work for the Flash uploader, mainly because the flash uploader doesn’t refresh the page.
However, this adds the ‘Insert’ button when a user uploads a file and passes the url back to your form when the button is pressed.
Tim, above, found a way to hack at core to get the button to display, however if, like me, hacking at core isn’t an option (I’m writing a plugin), then this may help you.
This could possible be extended by someone with some time finding out what function the Flash uploader calls and then writing some further javascript wrapper functions akin to the one in the file above.
You could also probably easily adjust it so that the ‘insert’ button is displayed always (i.e. before a file has been uploaded) and this would probably make it work for the flash uploader, too. Hope this helps! And I hope we get to a final conclusion soon!
For those with the “Insert Into Post” button problem in WP3: Turns out that the default Wordpress upload link includes one more GET variable: the post ID. Once that is included, the “Insert Into Post” button shows up. This is the click function I’m using:
jQuery(‘#upload_image_button’).click(function() {
formfield = jQuery(‘#upload_image’).attr(‘name’);
post_id = jQuery(‘#post_ID’).val();
tb_show(”, ‘media-upload.php?type=image&TB_iframe=true&send=true&post_id=’+post_id);
return false;
});
Disregard the comment above. That will only work if your custom post type supports ‘editor’.
This code on line 1166 of /wp-admin/includes/media.php:
$default_args = array( ‘errors’ => null, ’send’ => post_type_supports(get_post_type($post->post_parent), ‘editor’), ‘delete’ => true, ‘toggle’ => true….
just added some line to Matt’s js-script for to toggle between editor input and textfield. Works for me with WP 3 incl. “Insert Into Post” button”; postid is in container on the page.
jQuery(document).ready(function() {
var ww = jQuery(‘#post_id_reference’).text();
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor_clone = function(html){
imgurl = jQuery(‘img’,html).attr(’src’);
jQuery(‘#upload_image’).val(imgurl);
tb_remove();
}
jQuery(‘#add_image’).click(function() {
window.send_to_editor=window.original_send_to_editor;
tb_show(”, ‘media-upload.php?post_id=’ + ww + ‘&type=image&TB_iframe=true’);
return false;
});
jQuery(‘#upload_image_button’).click(function() {
window.send_to_editor=window.send_to_editor_clone;
formfield = jQuery(‘#upload_image’).attr(‘name’);
tb_show(”, ‘media-upload.php?post_id=’ + ww + ‘&type=image&TB_iframe=true’);
return false;
});
});
Thanks Norbert!
Keeping the editor’s uploader functional after adding a custom upload button was proving rather tricky for me. Thanks to you (and Matt, of course) it’s working now.
All-around great post and comments guys!
It sounds like a revamp of the Media Uploader is on the radar in trac. Keeping my fingers crossed…
This is the closest I’ve been thanks to you! That’s awesome. Although the Insert into Post button only seems to work when I click on Media Library, not in the window that pops open when I upload.
Thank so much for posting. Helped out a ton!
If you wanted to have more than one media upload button in the same page you can make in PHP in a loop (with $i):
Uploadimage
And in javascript :
jQuery(document).ready(function() {
var fileInput = '';
jQuery('.upload_image_button').click(function() {
fileInput = jQuery(this).prev('input');
formfield = nextInput.attr('name');
tb_show('', 'media-upload.php?type=image&TB_iframe=true');
return false;
});
jQuery('.upload_image').focusin(function() {
fileInput = jQuery(this);
formfield = jQuery(this).attr('name');
tb_show('', 'media-upload.php?type=image&TB_iframe=true');
return false;
});
window.send_to_editor = function(html) {
imgurl = jQuery('img',html).attr('src');
fileInput.val(imgurl);
tb_remove();
}
});
So you can have multiple inputs to upload images in the same page
This doesn’t seem to work for me??
Hey! Awesome article, I used this, but now it won’t allow me to insert images to a tinymce box…?
Any ideas on how to get both to work together?
See some of the above comments. It overrides something that breaks the normal post uploader.
Senica,
please try the code I modified from Matts post on July 1. It adds a click event
jQuery(‘#add_image’).click(function() {
to the standard editor box. That reinstalls the overwritten function.
So, you can insert images in the standard editor and in your textfield and vice versa
Please remind, that you have to put the WordPress Post ID in a location that can be accessed by jQuery.
I can’t do this work for me
The upload works but they don’t return nothing to my input.
Help please.
Andrea,
please read the above posts. The js script needs the post ID.
Find a workaround with Richard tapes post from June, 20th
Or use my js script from July 1st
I’ve been trying to use the “multiple” media uploader buttons script someone posted above, however I just can’t get it to work. I can get one to work, but no more than that. I’ve tried everything. Could someone please explain how to do it in an easier to understand version?
One thing I noticed…. You MUST leave the link url on the picture. If you take it off, it doesn’t work.
Thanks to you I was able to enable image upload to a plug – Runners Log – Im writing.
It need minor changes – but seems to work.
I did put in:
jQuery(document).ready(function() {…
In a tag just before the snippet:
Upload Image
Then Changed
function my_admin_scripts() {
wp_enqueue_script(‘media-upload’);
wp_enqueue_script(‘thickbox’);
wp_register_script(‘my-upload’, WP_PLUGIN_URL.’/my-script.js’, array(‘jquery’,'media-upload’,'thickbox’));
wp_enqueue_script(‘my-upload’);
}
function my_admin_styles() {
wp_enqueue_style(‘thickbox’);
}
if (isset($_GET['page']) && $_GET['page'] == ‘my_plugin_page’) {
add_action(‘admin_print_scripts’, ‘my_admin_scripts’);
add_action(‘admin_print_styles’, ‘my_admin_styles’);
}
to
function my_admin_scripts() {
wp_enqueue_script(‘media-upload’);
wp_enqueue_script(‘thickbox’);
}
function my_admin_styles() {
wp_enqueue_style(‘thickbox’);
}
add_action(‘admin_print_scripts’, ‘my_admin_scripts’);
add_action(‘admin_print_styles’, ‘my_admin_styles’);
Awesome, i learned a lot for your post and all the comments, thank you so much everyone. However i run into a problem. I would like to grab the ID of the attachment and save it in my field. Any idea how to do this?
Right now im using this:
var fileurl = jQuery(html).attr(‘href’);
So i can save the link of any file type not just the src of an image. It is not really pretty because, like one of the comment said, if the file link is set to NONE, it wont grab any info.
Im still a beginner so im a bit clueless as how to grab the attachment id when clicking “insert into post”. Does any one know how to? Is that information even there after i click “insert to post”?
Thanks in advance!
Hi there,
thanks for this tip. I am having trouble. I can open the upload window, I can upload an image, but when I click on the Insert Post button, the upload window disapeared but nothing happened. There is no URL inserted in the field. What am I missing? I am using WP 2.9.2. Thanks.
Hi guys,
It looks like (maybe with WP 3.0?) you need to pass the &page_id parameter in order for the “Insert” link to display.
So, you’d need to use this JS when invoking the page:
tb_show(”, ‘media-upload.php?type=image&post_id=1&TB_iframe=true’);
Thank you so much! Who would have thought I’d just have to add the 1…
I have upgraded to WP 3.0.1 and it started to work. But I have little problem. When I upload an image, then I press Insert to Post button, it insert to the field, but when I press Save button of the option page, the value from field dissapeares after refresh page. My other question is, how do I retrieve now the image to the theme template as for example a logo image. What value I should call.
What if I wanted to allow them to upload something other than an image file? For example I have this working to a point and allow users to upload a GPX file. All I had to do was remove the ‘type=image’ from the tb_show and Wordpress will handle what file types can be uploaded for me.
tb_show(”, ‘media-upload.php?type=image&TB_iframe=true’)
Launching the window and uploading the file is not the problem. It is getting the form text field to be populated with the GFX URL. I know I would have to change these lines….
imgurl = $(‘img’,html).attr(’src’);
jQuery(‘#upload_image’).val(imgurl);
… to get them to look for something other than ‘img’ and ’src’ But what?
Hi!
About insert into post.
And what happens, if you use this in your own page, where are no post id?
If i give a false post_id, it doesn’t works for me:
media-upload.php?type=image&TB_iframe=true&send=true&post_id=1
media-upload.php?type=image&TB_iframe=true&post_id=1
neither.
no error in console.
Has anyone been able to get multiple media uploaders to work?? I’ve looked at the comments, but none of that code is working?