How to Create a Custom WordPress Post Type With Image Uploads July 12 2012
This article details one method of creating a custom WordPress post type with the ability to upload and attach images using the built-in WordPress Media browser. This piece does not cover all the details and nuances of creating a custom post type, as this is covered well elsewhere. In addition to highlighting the most important methods and code required, I have attached a fully functional demo plugin which you may feel free to download and use as a starting point or reference. Also note that the code within this example is borrowed and modified from my favorite ecommerce platform: WooCommerce.
The Goal
My goal tonight was to create a custom post type and add a meta box to display, and allow admin users to select and attach an image using the WordPress media box:

I want the selected image to be displayed in a custom meta box, similar to the Post Featured Image box, and I want it to be dead simple for you to get this working in your own project.
The Code
Skipping the boilerplate code required to register the custom post type (which I’m calling “book”), set up the custom meta box, etc (which you can review in the demo plugin), the first piece of code to examine is the image display/upload/remove links:
global $post;
$image_src = '';
$image_id = get_post_meta( $post->ID, '_image_id', true );
$image_src = wp_get_attachment_url( $image_id );
?>
<img id="book_image" src="<?php echo $image_src ?>" style="max-width:100%;" />
<input type="hidden" name="upload_image_id" id="upload_image_id" value="<?php echo $image_id; ?>" />
<p>
<a title="<?php esc_attr_e( 'Set book image' ) ?>" href="#" id="set-book-image"><?php _e( 'Set book image' ) ?></a>
<a title="<?php esc_attr_e( 'Remove book image' ) ?>" href="#" id="remove-book-image" style="<?php echo ( ! $image_id ? 'display:none;' : '' ); ?>"><?php _e( 'Remove book image' ) ?></a>
</p>
This snippet pulls the attached image (if any) from the post, displays it, and creates the “Set” (or upload) and “Remove” links. Also note the hidden input field which used to persist the attached image id to the post meta.
Next we hook up the upload link:
window.send_to_editor_default = window.send_to_editor;
$('#set-book-image').click(function(){
// replace the default send_to_editor handler function with our own
window.send_to_editor = window.attach_image;
tb_show('', 'media-upload.php?post_id=<?php echo $post->ID ?>&type=image&TB_iframe=true');
return false;
});
The above javascript displays the WordPress media browser in the thickbox overlay when the “Set book image” link is clicked. With this and the previous piece of code the media browser will actually display and function as normal, until that you go to “Use this image” at which point the media box will go blank and not much else will happen. The reason for this is that when you choose an image from the media selector box it performs an asynchronous post to media-upload.php which returns a piece of Javascript similar to the following:
var win = window.dialogArguments || opener || parent || top;
win.send_to_editor('<a href="http://127.0.0.1/wp-content/uploads/2012/07/dracula.jpg"><img src="http://127.0.0.1/wp-content/uploads/2012/07/dracula.jpg" alt="" title="dracula" width="400" height="617" class="aligncenter size-full wp-image-1095" /></a>');
That call to win.send_to_editor() is sort of like invoking a callback or handler function, so we need to provide the function to do the image handling. That is the purpose of this line from above window.send_to_editor = window.attach_image;, so our next step is to provide that send_to_editor function, which in this example I’ve declared as attach_image():
window.attach_image = function(html) {
$('body').append('<div id="temp_image">' + html + '</div>');
var img = $('#temp_image').find('img');
imgurl = img.attr('src');
imgclass = img.attr('class');
imgid = parseInt(imgclass.replace(/D/g, ''), 10);
$('#upload_image_id').val(imgid);
$('#remove-book-image').show();
$('img#book_image').attr('src', imgurl);
try{tb_remove();}catch(e){};
$('#temp_image').remove();
window.send_to_editor = window.send_to_editor_default;
}
This function creates a temporary img tag with the selected image, so as to more easily parse out the url and id, which are then used to display the selected image in our meta box, and set the image id to that hidden form field so we can save it permanently to the post meta. Finally the function performs a little clean up by closing the media browser, removing that temporary image tag, and restoring the original send_to_editor handler.
That covers the most important and difficult pieces of code, all that remains is hooking up the “Remove” link with something like:
$('#remove-book-image').click(function() {
$('#upload_image_id').val('');
$('img').attr('src', '');
$(this).hide();
return false;
});
And finally saving that image id to the post:
add_action( 'save_post', 'book_meta_boxes_save', 1, 2 );
function book_meta_boxes_save( $post_id, $post ) {
if ( empty( $post_id ) || empty( $post ) || empty( $_POST ) ) return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( is_int( wp_is_post_revision( $post ) ) ) return;
if ( is_int( wp_is_post_autosave( $post ) ) ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
if ( $post->post_type != 'book' ) return;
update_post_meta( $post_id, '_image_id', $_POST['upload_image_id'] );
}
Demo Plugin
By now hopefully you have a solid understanding of how to make use of the media browser to attach an image to a custom post type. If you’d like a fully functional example to play around with and extend for your own uses, feel free to download and make use of my demo plugin:
Custom Post Type Image Upload Demo
[affiliate_disclaimer]
The post How to Create a Custom WordPress Post Type With Image Uploads appeared first on SkyVerge.