Languages: English • Русский • (Add your language)
wp.media
is used to handle and control the admin media modal. For instance, custom image selector/uploader controls and meta boxes. It is located in the wp scope/namespace.
One key use of this class is to create a custom image upload/select link. Let's assume you are creating a custom admin meta box with an image upload link, similar to the Set Featured Image link for WordPress posts.
To be able to use the JavaScript-API, you first have to init all the needed JavaScript-Libraries and Styles using the wp_enqueue_media() function:
wp_enqueue_media();
The wp_enqueue_media(); must be made during the action hook admin_enqueue_scripts or later. In the following example an anonymous function is used as the callback to admin_enqueue_scripts.
Note that 1 argument $hook_suffix is passed to the callback for admin_enqueue_scripts and this can be used to conditionally load the scripts based on which admin page is being viewed. Developers may also consider checking other conditions before loading the scripts so that the scripts are only loaded where needed.
add_action( 'admin_enqueue_scripts', function( $hook_suffix ) {
wp_enqueue_media();
}
This example achieves the same goal with a named function callback.
add_action( 'admin_enqueue_scripts', 'add_media_script' );
function add_media_script( $hook_suffix ) {
wp_enqueue_media();
}
The code below achieves the same goal as above and is designed for use in a PHP class:
class [PREFIX]_MediaHandler {
function __construct() {
// Pass a PHP callable method from the same class as the callback.
add_action( 'admin_enqueue_scripts', array( $this, 'add_media_script' ) );
}
function add_media_script( $hook_suffix ) {
wp_enqueue_media();
}
}
The wp_enqueue_media() function does a lot more than just enqueue required media files. It also does loading of data required for the media window to work. Therefore it is not (likely) possible to make the media scripts a dependency of an existing script the way we often would with other optional scripts like jQuery UI scripts. If the required data doesn't load, the WP Media scripts will fail.
Your meta box PHP might look like this...
<?php
global $post;
// Get WordPress' media upload URL
$upload_link = esc_url( get_upload_iframe_src( 'image', $post->ID ) );
// See if there's a media id already saved as post meta
$your_img_id = get_post_meta( $post->ID, '_your_img_id', true );
// Get the image src
$your_img_src = wp_get_attachment_image_src( $your_img_id, 'full' );
// For convenience, see if the array is valid
$you_have_img = is_array( $your_img_src );
?>
<!-- Your image container, which can be manipulated with js -->
<div class="custom-img-container">
<?php if ( $you_have_img ) : ?>
<img src="<?php echo $your_img_src[0] ?>" alt="" style="max-width:100%;" />
<?php endif; ?>
</div>
<!-- Your add & remove image links -->
<p class="hide-if-no-js">
<a class="upload-custom-img <?php if ( $you_have_img ) { echo 'hidden'; } ?>"
href="<?php echo $upload_link ?>">
<?php _e('Set custom image') ?>
</a>
<a class="delete-custom-img <?php if ( ! $you_have_img ) { echo 'hidden'; } ?>"
href="#">
<?php _e('Remove this image') ?>
</a>
</p>
<!-- A hidden input to set and post the chosen image id -->
<input class="custom-img-id" name="custom-img-id" type="hidden" value="<?php echo esc_attr( $your_img_id ); ?>" />
To properly control the above HTML, you would use the following Javascript...
jQuery(function($){
// Set all variables to be used in scope
var frame,
metaBox = $('#meta-box-id.postbox'), // Your meta box id here
addImgLink = metaBox.find('.upload-custom-img'),
delImgLink = metaBox.find( '.delete-custom-img'),
imgContainer = metaBox.find( '.custom-img-container'),
imgIdInput = metaBox.find( '.custom-img-id' );
// ADD IMAGE LINK
addImgLink.on( 'click', function( event ){
event.preventDefault();
// If the media frame already exists, reopen it.
if ( frame ) {
frame.open();
return;
}
// Create a new media frame
frame = wp.media({
title: 'Select or Upload Media Of Your Chosen Persuasion',
button: {
text: 'Use this media'
},
multiple: false // Set to true to allow multiple files to be selected
});
// When an image is selected in the media frame...
frame.on( 'select', function() {
// Get media attachment details from the frame state
var attachment = frame.state().get('selection').first().toJSON();
// Send the attachment URL to our custom image input field.
imgContainer.append( '<img src="'+attachment.url+'" alt="" style="max-width:100%;"/>' );
// Send the attachment id to our hidden input
imgIdInput.val( attachment.id );
// Hide the add image link
addImgLink.addClass( 'hidden' );
// Unhide the remove image link
delImgLink.removeClass( 'hidden' );
});
// Finally, open the modal on click
frame.open();
});
// DELETE IMAGE LINK
delImgLink.on( 'click', function( event ){
event.preventDefault();
// Clear out the preview image
imgContainer.html( '' );
// Un-hide the add image link
addImgLink.removeClass( 'hidden' );
// Hide the delete image link
delImgLink.addClass( 'hidden' );
// Delete the image id from the hidden input
imgIdInput.val( '' );
});
});
For more information on adding custom meta boxes to WordPress, see add_meta_box() or the Example Meta Box Plugin on Github
The source is defined in js/_enqueues/wp/media/models.js
and output in `wp-includes/js/media-models.js` during build.