Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Javascript Reference/wp.media

This page is marked as incomplete. You can help Codex by expanding it.

Description

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.

Example

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.

Enqueue Required Media Script

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();

  }

}

Further Notes on Media Script Enqueue

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

Location

The source is defined in js/_enqueues/wp/media/models.js and output in `wp-includes/js/media-models.js` during build.

External Resources

Related