Using the REST API to upload a file to WordPress is
quite simple. All you need is to send the file in a
POST
-Request to the wp/v2/media
route.
There are two ways of sending a file. The first method simply sends the file in the body of the request. The following PHP script shows the basic principle:
<?php
$file = file_get_contents( 'test.jpg' );
$url = 'http://example.com/wp-json/wp/v2/media/';
$ch = curl_init();
$username = 'admin';
$password = 'password';
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $file );
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
'Content-Disposition: form-data; filename="example.jpg"',
'Authorization: Basic ' . base64_encode( $username . ':' . $password ),
] );
$result = curl_exec( $ch );
curl_close( $ch );
print_r( json_decode( $result ) );
This would send the file test.jpg using CURL and create a new attachment.
You need to make sure, you are logged in as a user, who can
upload media files. In our example, we are using Basic
authentication. Via the headers you also have to send the
Content-Disposition
where you also add the filename.
The file itself is simply send in the body of the request.
The disadvantage of this way is, you can upload the file,
but you can not alter the title
or the caption
in the
same process. You would need to wait for the response and
you would need to update the created media object in a
second request.
Have a look into this small plugin, to see one possibility, how to upload a file using Javascript:
plugin.php
<?php
/**
* Plugin Name: Upload a file via the REST API
* Description: Upload a file with Javascript using the Rest API.
* License: GPLv2
*/
add_action( 'wp_enqueue_scripts', function() {
wp_register_script( 'rest-uploader', plugins_url( '/assets/js/script.js', __FILE__ ), [ 'jquery' ] );
$js_vars = [
'endpoint' => esc_url_raw( rest_url( '/wp/v2/media/' ) ),
'nonce' => wp_create_nonce( 'wp_rest' ),
];
wp_localize_script( 'rest-uploader', 'RestVars', $js_vars );
} );
add_shortcode( 'uploader', function() {
wp_enqueue_script( 'rest-uploader' );
ob_start();
?>
<h2><?php esc_html_e( 'Upload a file', 'rest-uploader' ); ?></h2>
<form method="post">
<p>
<label for="uploader-title">
<?php esc_html_e( 'Title', 'rest-uploader' ); ?>:
</label>
<input id="uploader-title">
</p>
<p>
<label for="uploader-caption">
<?php esc_html_e( 'Caption', 'rest-uploader' ); ?>:
</label>
<input id="uploader-caption">
</p>
<p>
<label for="uploader-file">
<?php esc_html_e( 'File', 'rest-uploader' ); ?>:
</label>
<input id="uploader-file" type="file">
</p>
<button id="uploader-send"><?php esc_html_e( 'Send', 'rest-uploader' ); ?></button>
</form>
<?php
$content = ob_get_contents();
ob_end_clean();
return $content;
} );
In this plugin, we simply add a shortcode, which renders a basic form and hooks the following Javascript in:
assets/js/script.js
jQuery( document ).ready( function() {
jQuery( '#uploader-send' ).click( function( event ) {
event.preventDefault();
var title = jQuery( '#uploader-title' ).val();
if ( ! title.length ) {
alert( 'Please enter a title!' );
}
var caption = jQuery( '#uploader-caption' ).val();
if ( ! caption.length ) {
alert( 'Please enter a caption!' );
}
// Check, if a file is selected.
if ( 'undefined' === typeof( jQuery( '#uploader-file' )[0].files[0] ) ) {
alert( 'Select a file!' );
return;
}
// Grab the file from the input.
var file = jQuery( '#uploader-file' )[0].files[0];
var formData = new FormData();
formData.append( 'file', file );
formData.append( 'title', title );
formData.append( 'caption', caption );
// Fire the request.
jQuery.ajax( {
url: RestVars.endpoint,
method: 'POST',
processData: false,
contentType: false,
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', RestVars.nonce );
},
data: formData
} ).success( function ( response ) {
console.log( response.id )
} ).error( function( response ) {
console.log( 'error' );
console.log( response );
});
} );
});
Basically, we are using Javascripts FormData
-class to generate our form data and
send this data to our rest endpoint. As we are not using the while requests body to send
the file, in this example, we can upload a file and create the attachment in one request.