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!