Insert MediaIn a custom plugin I made, I had to add a custom media upload button in order to make sure only a single Video file is can be selected.
After doing some research, I discovered the handy & pretty undocumented component: wp.media

Just to make sure we’re on the same page, this is a JavaScript component which is a part of WordPress, used to handle Media upload (when writing a post).
If you're not sure how to add fields/buttons within post editing, take a look at the add_meta_boxes action, just so you can understand the context.
 
Let’s start with a simple upload button:

1
<input type=”button” value=”Upload Video” class=”upload_vid” />

And the following JS snippet:

1
2
3
4
5
jQuery( 'body' ).on( 'click', '.upload_vid', function(e) {
	e.preventDefault();
	var foo = wp.media();
	foo.open();
});

This will simply open up a Media Upload dialog (with the default configuration), it won’t be that functional because we’re not doing anything with the selected media yet.

We’d like to only be able to select a single Video file, so here are the relevant changes (for the sake of brevity I only show the wp.media() line, the rest is the same for now):

1
2
3
4
var foo = wp.media({
	library     : { type : 'video' },
	multiple    : false
});

As you can probably guess, the 1st line limits to videos, and the 2nd disables multiple select.
Let’s also add some title & custom submit button text:

1
2
3
4
5
6
var foo = wp.media({
	title       : AWESOME Video Upload Title!',
	button      : { text : ‘Add this AWESOME video!' }
	library     : { type : 'video' },
	multiple    : false,
});

Cool, ok now we have a custom upload dialog, all that’s left is to actually do something with the submitted videos.
wp.media has an event called close, we can access the frame using that, let’s add the following event (still inside the onclick event) + html:

HTML:

1
2
3
<input type=”button” value=”Upload Video” class=”upload_vid” />
<span class=”id_of_vid”></span>
<span class=”link_to_vid”></span>

JS:

1
2
3
4
5
foo.on( 'close', function() {
	var videos = foo.state().get( 'selection' ).toJSON();
	jQuery( .id_of_vid ).text( videos[0].id );
	jQuery( .link_to_vid ).text( videos[0].url );
} );

This will show you the ID of the selected video inside the id_of_vid span (and the URL on the other span), obviously the object inside videos[0] has Title, Filename, and so on, so you can do whatever you’d like with it.

What about saving your selection?

Let’s utilize the fact that we have the ID inside the id_of_vid span, to make sure the video is already selected when re-opening the dialog (this time, using the open event):

1
2
3
4
5
6
7
8
9
foo.on( 'open', function() {
	var selection = foo.state().get( 'selection' );
	var vids = jQuery( .id_of_vid ).text();
	if ( vids !== '' ) {
		attachment = wp.media.attachment( vids );
		attachment.fetch();
		selection.add( attachment ? [ attachment ] : [] );
	}
});</p>

As you can see this is a bit complex, but at the end of the day we’re using the selection object we used earlier, and adding to it an attachment object (created using the ID inside id_of_vid).

I hope I’ve given enough tools so everyone can make some custom wp.media widgets, this would’ve definitely saved me a lot of trouble a few days ago.

See you next week!