I would like to implement an inline file uploader to my plugin's option page as introduced in new media grid view of the WP media library:
I imagine having this drag & drop uploader in the page and getting an JSON object of either errors or attachment data back in JS when used.
As far as I know there is a wp.media.view.UploaderInline
class present in
wp-includes/js/media-views.js
but I have no idea of how to implement that in combination with the given markup.
The only resources I found are on how to use the media modal (introduced in v3.5) to upload and add files to a page. But having the uploader inline would be much better for my case since I don't want the media library to show up in the process.
Has anyone experience implementing this to get me on track?
Thx
I would like to implement an inline file uploader to my plugin's option page as introduced in new media grid view of the WP media library:
I imagine having this drag & drop uploader in the page and getting an JSON object of either errors or attachment data back in JS when used.
As far as I know there is a wp.media.view.UploaderInline
class present in
wp-includes/js/media-views.js
but I have no idea of how to implement that in combination with the given markup.
The only resources I found are on how to use the media modal (introduced in v3.5) to upload and add files to a page. But having the uploader inline would be much better for my case since I don't want the media library to show up in the process.
Has anyone experience implementing this to get me on track?
Thx
Okay, here is what I came up with: It's all about using the plupload library that comes shipped with WP.
<div>
to your plugin's option page that later becomes the drag'n'drop area <div class="your-plugin-uploader multiple">
<input id="your-plugin-uploader-button" type="button" value="<?php esc_attr_e( 'Select Files' ); ?>" class="your-plugin-uploader-button button">
<span class="ajaxnonce" id="<?php echo wp_create_nonce( __FILE__ ); ?>"></span>
</div>
plupload-all
as a dependency for your script function se179618_admin_js() {
wp_register_script( 'your-plugin', WP_PLUGIN_URL . '/your-plugin/js/your-plugin.js', array( 'jquery', 'plupload-all' ) );
}
add_action( 'admin_enqueue_scripts', 'se179618_admin_js' );
<head>
function se179618_admin_head() {
$uploader_options = array(
'runtimes' => 'html5,silverlight,flash,html4',
'browse_button' => 'my-plugin-uploader-button',
'container' => 'my-plugin-uploader',
'drop_element' => 'my-plugin-uploader',
'file_data_name' => 'async-upload',
'multiple_queues' => true,
'max_file_size' => wp_max_upload_size() . 'b',
'url' => admin_url( 'admin-ajax.php' ),
'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ),
'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
'filters' => array(
array(
'title' => __( 'Allowed Files' ),
'extensions' => '*'
)
),
'multipart' => true,
'urlstream_upload' => true,
'multi_selection' => true,
'multipart_params' => array(
'_ajax_nonce' => '',
'action' => 'my-plugin-upload-action'
)
);
?>
<script type="text/javascript">
var global_uploader_options=<?php echo json_encode( $uploader_options ); ?>;
</script>
<?php
}
add_action( 'admin_head', 'se179618_admin_head' );
function se179618_ajax_action() {
// check ajax nonce
check_ajax_referer( __FILE__ );
if( current_user_can( 'upload_files' ) ) {
$response = array();
// handle file upload
$id = media_handle_upload(
'async-upload',
0,
array(
'test_form' => true,
'action' => 'my-plugin-upload-action'
)
);
// send the file' url as response
if( is_wp_error( $id ) ) {
$response['status'] = 'error';
$response['error'] = $id->get_error_messages();
} else {
$response['status'] = 'success';
$src = wp_get_attachment_image_src( $id, 'thumbnail' );
$response['attachment'] = array();
$response['attachment']['id'] = $id;
$response['attachment']['src'] = $src[0];
}
}
echo json_encode( $response );
exit;
}
add_action( 'wp_ajax_my-plugin-upload-action', 'se179618_ajax_action' );
jQuery( document ).ready( function() {
if( jQuery( '.your-plugin-uploader' ).length > 0 ) {
var options = false;
var container = jQuery( '.your-plugin-uploader' );
options = JSON.parse( JSON.stringify( global_uploader_options ) );
options['multipart_params']['_ajax_nonce'] = container.find( '.ajaxnonce' ).attr( 'id' );
if( container.hasClass( 'multiple' ) ) {
options['multi_selection'] = true;
}
var uploader = new plupload.Uploader( options );
uploader.init();
// EVENTS
// init
uploader.bind( 'Init', function( up ) {
console.log( 'Init', up );
} );
// file added
uploader.bind( 'FilesAdded', function( up, files ) {
jQuery.each( files, function( i, file ) {
console.log( 'File Added', i, file );
} );
up.refresh();
up.start();
} );
// upload progress
uploader.bind( 'UploadProgress', function( up, file ) {
console.log( 'Progress', up, file )
} );
// file uploaded
uploader.bind( 'FileUploaded', function( up, file, response ) {
response = jQuery.parseJSON( response.response );
if( response['status'] == 'success' ) {
console.log( 'Success', up, file, response );
} else {
console.log( 'Error', up, file, response );
}
} );
}
} );
Here is an example for wp version 4.7 and above. The task is simple. This code is directly cloned script taken from the default Wordpress Add new page (media-new.php).
function my_admin_enqueue_scripts() {
wp_enqueue_script('plupload-handlers');
}
add_action('admin_enqueue_scripts', 'my_admin_enqueue_scripts');
Add this html on your options page. Make shure you keep this outside your own <form>
element. To keep the variables out of global scope, I recommend to wrap the html output inside a function. This example is lending the top admin notices container to show the area on every admin page... so you can test it without option page.
function my_upload_new_media_html(){
/* everything is copied from media-new.php */
/* translated, and old browser option is there as well */
$title = __('Upload New Media');
$post_id = 0;
if(isset($_REQUEST['post_id'])){
$post_id = absint($_REQUEST['post_id']);
if(!get_post($post_id) || !current_user_can('edit_post', $post_id)) $post_id = 0;
}
if($_POST){
if(isset($_POST['html-upload']) && !empty($_FILES)){
check_admin_referer('media-form');
// Upload File button was clicked
$upload_id = media_handle_upload('async-upload', $post_id);
if(is_wp_error($upload_id)){
wp_die($upload_id);
}
}
wp_redirect(admin_url('upload.php'));
exit;
}
$form_class = 'media-upload-form type-form validate';
if(get_user_setting('uploader') || isset( $_GET['browser-uploader']))
$form_class .= ' html-uploader';
?>
<div class="wrap">
<h1><?php echo esc_html( $title ); ?></h1>
<form enctype="multipart/form-data" method="post" action="<?php echo admin_url('media-new.php'); ?>" class="<?php echo esc_attr( $form_class ); ?>" id="file-form">
<?php media_upload_form(); ?>
<script type="text/javascript">
var post_id = <?php echo $post_id; ?>, shortform = 3;
</script>
<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
<?php wp_nonce_field('media-form'); ?>
<div id="media-items" class="hide-if-no-js"></div>
</form>
</div>
<?php
}
add_action('all_admin_notices', 'my_upload_new_media_html');
And Boom, its there.
The first thing you'll need to do is call wp_enqueue_media
. A safe place for this might be in the admin_init
action with some conditional around it.
add_action( 'admin_init', function() {
$screen = get_current_screen();
if ( ! $screen || 'my-admin-page-slug' !== $screen->id ) {
return;
}
wp_enqueue_media();
} );
Then in your admin page code you'd add some inline javascript (or enqueue it if you want to do it cleanly)
function my_admin_page_callback() {
...
?>
<a href="#" class="primary button upload">Upload</a>
<script type="text/javascript">
$('.upload.button').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();
// Do something with attachment.url;
// Do something with attachment.id;
})
.open();
});
</script>
<?php
...
}
Getting the drag and drop box might prove a little difficult but if you do a little digging of your own you might be able to find it.