67
votes

WordPress 3.5 has been released recently, I used the WordPress Media Upload system via thickbox and window.send_to_editor for some options in my WordPress theme (backgrounds, logos etc...).

But as you know WordPress has integrated a new Media Manager, I wanted to used this new feature to upload images/files as custom fields. So I spent the morning to find a way to get the wished result.

I found with this solution, which can be useful for some of you. Thanks to give me your feedback on the code or any improvements you have in mind!

HTML Sample:

<a href="#" class="custom_media_upload">Upload</a>
<img class="custom_media_image" src="" />
<input class="custom_media_url" type="text" name="attachment_url" value="">
<input class="custom_media_id" type="text" name="attachment_id" value="">

jQuery Code:

$('.custom_media_upload').click(function() {

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

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

        $('.custom_media_image').attr('src', attachment.url);
        $('.custom_media_url').val(attachment.url);
        $('.custom_media_id').val(attachment.id);

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

    wp.media.editor.open();

    return false;
});

If you want to see every settings contained in the attachment variable you can do a console.log(attachment) or alert(attachment).

5
Wordpress admin uses noConflict so I had to change the $ -> jQuery. Very helpful thanks!styks
Thanks a zillion for that crisp example! Passing a post ID is as simple as passing it as a param in the wp.media.editor.open()Jos Faber
I'm wondering how to load Media API as dependency to some script in wp_enqueue_script(). I know that wp_enqueue_media() is there but I'd prefer to use dependency - is there a way to do this?Atadj

5 Answers

33
votes

Don't forget to use wp_enqueue_media (new in 3.5) if you'r not on the post edit page

To use the old media upload box you can do this:

if(function_exists( 'wp_enqueue_media' )){
    wp_enqueue_media();
}else{
    wp_enqueue_style('thickbox');
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
}
35
votes

Your going about it in a way that was unintended. Your javascript code should probably look something like this:

$('.custom_media_upload').click(function(e) {
    e.preventDefault();

    var custom_uploader = wp.media({
        title: 'Custom Title',
        button: {
            text: 'Custom Button Text'
        },
        multiple: false  // Set this to true to allow multiple files to be selected
    })
    .on('select', function() {
        var attachment = custom_uploader.state().get('selection').first().toJSON();
        $('.custom_media_image').attr('src', attachment.url);
        $('.custom_media_url').val(attachment.url);
        $('.custom_media_id').val(attachment.id);
    })
    .open();
});
7
votes

I modified this code a bit more to make it usable for multiple fields at once:

HTML:

<!-- Image Thumbnail -->
<img class="custom_media_image" src="" style="max-width:100px; float:left; margin: 0px     10px 0px 0px; display:inline-block;" />

<!-- Upload button and text field -->
<input class="custom_media_url" id="" type="text" name="" value="" style="margin-bottom:10px; clear:right;">
<a href="#" class="button custom_media_upload">Upload</a>

jQuery:

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

$('.custom_media_upload').click(function() {

        var send_attachment_bkp = wp.media.editor.send.attachment;
        var button = $(this);

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

            $(button).prev().prev().attr('src', attachment.url);
            $(button).prev().val(attachment.url);

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

        wp.media.editor.open(button);

        return false;       
    });

});
4
votes

I found nothing to trigger a custom function if the editor closes. I uses this:

wp.media.editor.open();
$('.media-modal-close, .media-modal-backdrop').one('click', function(){
    //do some stuff
});

or better:

var id = wp.media.editor.id();
var editor = wp.media.editor.get( id );
if('undefined' != typeof( editor )) editor = wp.media.editor.add( id );

if ( editor ) {
    editor.on('close', function(){
        //do some stuff
    });
}
3
votes

I haven't had much chance to play with this, but for those looking to leverage the gallery element, this code should set you on your way.

It is just a start point - it only provides a comma separated list of image id's, but that should be enough to start being creative.

<input id="custom_media_id" type="text" name="attachment_id" value="">
<a href="#" class="button custom_media_upload" title="Add Media">Add Media</a>

<script type="text/javascript">
  jQuery('.custom_media_upload').click(function() {
    var clone = wp.media.gallery.shortcode;
    wp.media.gallery.shortcode = function(attachments) {
    images = attachments.pluck('id');
    jQuery('#custom_media_id').val(images);
    wp.media.gallery.shortcode = clone;
    var shortcode= new Object();
    shortcode.string = function() {return ''};
    return shortcode;
  }
jQuery(this).blur(); // For Opera. See: http://core.trac.wordpress.org/ticket/22445
wp.media.editor.open();
return false;       
});
</script>

This will populate the input field with a comma separated list of the image id's, in the order they were set in the editor (using the new drag and drop functionality).

The function expects the shortcode to be sent back for placement in the main editor, but we don't want to do this, so we create a new object that returns a blank string for insertion.

Also note, this doesn't handle inserting a single image as described above - it'll just put it into the post editor. So try combining the two listeners, or remove the appropriate tabs.

EDIT

Having spent some time looking at the core, I think this whole process can actually be done easier using the technique laid out here, but as you'll read I haven't figured out yet how to pre-select the images when you reopen the media manager.