Multiple upload inputs in a WordPress theme options page?

WordPress settings API

Lots of info and tutorials on the net on the subject of WordPress “theme options” or  ”admin” pages. Many of them are out dated and don’t subscribe to the current best practices as outlined by WordPress – in other words the settings API. Nettuts is always a great place to start. In my case, the tutorial the resinated the most with me was a fairly recent post by Aliso The Geek. Her tutorial is clear, easy to follow, results in a organized tabbed theme options page and best of all, your new WordPress theme options page will be 100% contained within a tidy class file – easily transferred from theme to theme is so desired.

So what’s left to expound upon?

Not much, unless you’d like to include and upload field. The easiest way to implement this, with some possible pitfalls (more on this later), is to use WordPress’ built in Media Uploader and Thinkbox script.

Step one: Back to your theme options class

Since we are adding a new “type” we’re going to need to add a new case to the switch statement.

case 'upload':
default:
   echo '<input id="' . $id . '" class="upload-url' . $field_class . '" type="text" name="mytheme_options[' . $id . ']" value="' . esc_attr( $options[$id] ) . '" />'
   '<input id="st_upload_button" class="st_upload_button" type="button" name="upload_button" value="Upload" />';

if ( $desc != '' )
   echo '
   <span class="description">' . $desc . '</span>';

break;

Essentially the same as the ‘text’ case. Change type to “file”, add an input button with a class of “st_upload_button” (or whatever you so desire) that will later trigger the media uploader.

Step Two: Add the upload field Array

		$this->settings['st_upload'] = array(
			'title'   => __( 'Example upload Input' ),
			'desc'    => __( 'This is a description for the upload input.' ),
			'std'     => 'My logo',
			'type'    => 'upload',
			'section' => 'general'
		);

Nothing new here…

  1. Name it what you want
  2. Your title
  3. Your description
  4. Default Value (for the text field in this case)
  5. Type (our new type, yay)
  6. Whatever section you’d like to appear

Refresh your WordPress theme options page and your upload field should be present and look something like this:

Step Three: Gather the tools

First we need to load a few scripts and styles.

  1. Medial Uploader script
  2. Thickbox script
  3. Thickbox CSS
  4. And finally, “my-upload” script

We already have a scripts() and styles() function in our class, so this is really quite easy.

//Media Uploader Scripts
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
wp_register_script('my-upload', get_bloginfo( 'stylesheet_directory' ) . '/js/uploader.js', array('jquery','media-upload','thickbox'));
wp_enqueue_script('my-upload');
//Media Uploader Style
wp_enqueue_style('thickbox');

Step Four: Make it do something cool

jQuery(document).ready(function() {

	jQuery('.st_upload_button').click(function() {
		 targetfield = jQuery(this).prev('.upload-url');
		 tb_show('', 'media-upload.php?type=image&amp;TB_iframe=true');
		 return false;
	});

	window.send_to_editor = function(html) {
		 imgurl = jQuery('img',html).attr('src');
		 jQuery(targetfield).val(imgurl);
		 tb_remove();
	}

});

When the upload button is clicked, we launch the WordPress media uploader and set the ‘targetfield’ variable to the previous text input. We’ll swing back around for this later. Next we overwrite send_to_editor,  get the image URL from the SCR attribute and then finally put that value in the target field.

Pitfalls?

My main complaint with the media uploader in this situation is it’s not particularly intuitive for clients or people not familiar with the finner details of WordPress. One has to either upload an image or choose from the media library and then click “insert into post”. On the other hand, it is consistent with the rest of the WordPress GUI and allows you to choose from already uploaded images.