WordPress 3.3 introduced a new, unified media menu, where the functionality that used to be accessed through several different menus is now all in one. If you are a plugin developer, and you want to create a custom media menu, you will discover WordPress’ media menu is an arcane and fickle beast. The general reason it’s challenging to work with is that the media menu lacks a complete API. I put several hours of code archaeology work into teasing out its functionality, so this post can guide you through using it. There are two approaches.
The WordPress media menu is displayed using ThickBox. One approach is to simply invoke ThickBox directly from your own media button, and not rely on WordPress’ filters or hooks beyond that. This is the simplest approach, and is suitable for many purposes, but it prevents you from using WordPress’ filters and hooks for applying stylesheets to it, or using menu tabs. This is the approach used by the Gravity Forms plugin. Here is the relevant parts of the Gravity Forms code, slightly re-arranged, to show how it all fits together:
add_action('media_buttons_context', array('RGForms', 'add_form_button')); public static function add_form_button($context){ $image_btn = GFCommon::get_base_url() . "/images/form-button.png"; $out = '<a href="#TB_inline?width=480&inlineId=select_gravity_form" class="thickbox" id="add_gform" title="' . __("Add Gravity Form", 'gravityforms') . '"><img src="'.$image_btn.'" alt="' . __("Add Gravity Form", 'gravityform') . '" /></a>'; return $context . $out; }
if(in_array(RG_CURRENT_PAGE, array('post.php', 'page.php', 'page-new.php', 'post-new.php'))){ add_action('admin_footer', array('RGForms', 'add_mce_popup')); }
send_to_editor
passes the resulting Gravity Forms shortcode to the editor window. After that is the html code that displays the form. The display: none
style is important: the form is hidden at the bottom of the editor page, and then shown in the ThickBox window when the media button is clicked (the media button link refers to the id of this div). I’ve also removed the input form, which has all its CSS styling done inline (with this approach, there’s no straightforward way to call an external stylesheet).
function add_mce_popup(){ // ...not shown - javascript that reads the form inputs window.send_to_editor("[gravityform id=\"" + form_id + "\" name=\"" + form_name + "\"" + title_qs + description_qs + ajax_qs + "]"); // ... <div id="select_gravity_form" style="display:none;"> // ...not shown - html for the form }
Due to a code change in WordPress 3.3, you can no longer use your own media button if you want to create a menu with custom tabs (or, at least, I couldn’t figure out how). With this approach, your menu will be accessible as a new tab in WordPress 3.3’s unified media menu. I’ll use code from my Shashin plugin as an example.
$tabs
contains the pre-defined WordPress menu tabs)
add_filter('media_upload_tabs', array($this, 'addMediaMenuTabs')); public function addMediaMenuTabs($tabs) { $shashinTabs = array( 'shashinPhotos' => __('Shashin Photos', 'shashin'), 'shashinAlbums' => __('Shashin Albums', 'shashin') ); return array_merge($tabs, $shashinTabs); }
media_upload_*
action to register the functions that will load the contents for the Shashin menus. It’s crucial that the last portion of the action name match the array keys added to the tabs in the previous step.
add_action('media_upload_shashinPhotos', array($this, 'initPhotoMediaMenu')); add_action('media_upload_shashinAlbums', array($this, 'initAlbumMediaMenu'));
admin_print_styles
with -media-upload-popup
lets you pass your own css file to the media menu, for your custom tab. wp_iframe
loads your html into menu.
public function initPhotoMediaMenu() { add_action('admin_print_styles-media-upload-popup', array($this, 'displayMediaMenuCss')); return wp_iframe(array($this, 'mediaDisplayPhotoMenu')); }
public function displayMediaMenuCss() { $cssUrl = plugins_url('/Display/', __FILE__) .'media.css'; wp_enqueue_style('shashinMediaMenuStyle', $cssUrl, false, $this->version); }
media_upload_header
loads the menu tabs. After that, put in your javascript and html for what you want to display for this tab. Like the Gravity Forms example above, you need to call WordPress’ send_to_editor javascript function to insert the final result into the editor.
public function mediaDisplayPhotoMenu() { media_upload_header(); // ... not shown - javascript and html for the menu }
Before WordPress 3.3, the Shashin plugin had its own media button, that launched a media menu with two custom tabs. From what I can tell, there is no straightforward way to do this in WordPress 3.3. It used to be possible to have tabs that were independent of the tabs that are part of the standard WordPress media uploader. But now if you want to have custom tabs, you can’t have them as part of a custom menu – you have to add them to the existing media uploader tabs. So for Shashin, I decided to take this approach, as the only alternative would be to add two buttons to the media button bar, and have two separate media menus instead of one menu with two tabs.
Update 12/13: the Shashin media menu is not working in WordPress 3.3. I’ll see how they’ve changed the media menu and try to have a fix in the next few days. In the meantime, you can still add shortcodes by hand (you can see the album ids and photo ids in the Shashin Tools menu).
Update 12/14: ….And I just uploaded a fix – version 3.0.9. Note that the Shashin media menus are now available as tabs within WordPress 3.3’s new, unified media menu. So Shashin no longer has it’s own media button. I’ll explain why in an upcoming post.
Last night I uploaded Shashin 3.0.8. If you were browsing photos in one album after another, in some circumstances you’d get spurious Highslide navbars stacking up on the top left side of the page. It’s fixed now. It had to do with the complexities of having different kinds of photo groupings going on at the same time in Shashin – there can be multiple groups of albums on a page, groups of photos within albums, photo-by-photo navigation within Highslide, and “page-by-page” navigation using the Shashin “next” and “previous” links. Getting all of them working together seamlessly has proven to be the most challenging (and therefore rewarding!) part of working on Shashin.
I expect this to be the last maintenance release for Shashin 3.0 (knocking on wood, crossing fingers…). For 3.1 I am planning to add support for Highslide thumbstrips and introduce lazy loading of the photos. I had done some initial work on adding Flickr support, but the Flickr API is fairly complex, so I’m going to put off Flickr to version 3.2, as I’ve been getting a lot of requests for the thumbstrips feature.
Please use the comments section for any support questions.
Video of my Clean Code for WordPress presentation at WordCamp Philly is available at wordpress.tv. You can also check out the other presentation videos available so far. Every session was recorded, so eventually they’ll all be online (Doug Stewart is doing a great job editing them, so they’re worth the wait). Poka Yoke Design provided the photography, and they’ve posted a bunch of great pictures. Here are a few they took of me.
Update 11/21: I’ve upload Shashin 3.0.5, which fixes this issue, reported in the wordpress.org forums
I uploaded two updates to wordpress.org last night – one for Post to Post Links II error: No post found with slug "shashin-wordpress-plugin" and one for Post to Post Links II error: No post found with slug "toppa-plugin-libraries-for-wordpress". They address a couple bugs in Shashin:
Another cause of the album thumbnail clicks not working is the jQuery form validation plugin. This plugin comes with the Arras theme. I’m still investigating why (there are no forms in Shashin, so offhand I don’t know why there would be a conflict). If you want to temporarily disable the form validation in Arras, go to line 46 in its header.php file and comment it out, like this:
//wp_enqueue_script('jquery-validate', get_template_directory_uri() . '/js/jquery.validate.min.js', 'jquery', null, false);
The Toppa Plugin Libraries update also include a new class for simplifying management of plugin settings (for any plugin that wants to use it). I’ll document it shortly.
Please use the comments section of this post to report any other issues.
I uploaded some Shashin fixes yesterday. Thanks everyone for the feedback. These were the changes:
Please use the comment section for reporting problems. I have a hectic week coming up, so it may take me a few days to respond to feedback. Thanks for your patience.
Update 11/21: Video of my presentation is now available at wordpress.tv, and I put up a post yesterday with more pictures.
WordCamp Philly this past weekend was a blast, and I met a lot of great people. The vibrancy of the WordPress community here in Philly is impressive. Giving my Clean code for WordPress presentation was also a lot of fun. I got vigorous agreement from the audience that more evangelism for clean code in WordPress plugins is definitely needed. Video of my presentation will be online at wordpress.tv in a few weeks.
The youngest attendee was 10 years old. He came to the developers’ day on Sunday too. The organizers were planning to guide him through fixing a bug in WordPress core, so he could be the youngest contributor to WordPress and get his name on the official credits. I spent the developers’ day getting started on adding Flickr support to Post to Post Links II error: No post found with slug "shashin-wordpress-plugin". I’m not a Flickr user, but I was sitting next to Captin Shmit, who is, and he had a lot of useful suggestions. Thanks Captin! (yes that’s how he spells it).
Below are the slides from my presentation (if you click the link, it will take you to slideshare.net, where you can also see my notes for the slides).
Tonight I pushed a set of updates to Shashin that should address most of the issues people have reported in the last 24 hours. I tried to be thorough in the development and beta testing, so I’m glad to see most of the issues are minor. Thanks everyone for the detailed reports. Note you will also need to update Toppa Plugin Libraries for WordPress. Here’s the list of updates in Shashin 3.0.2 (from the readme file):
Over the past year I’ve worked on Shashin 3 in 20 minute pomodoro-like sessions, to give myself something interesting to do on my daily train commute back and forth to work. I’ve used it to teach myself clean code practices. How to apply clean code practices to WordPress plugin development will be the subject of my talk next weekend at Philly WordCamp.
If you haven’t seen the posts I’ve been writing while I’ve been working on it, see the Post to Post Links II error: No post found with slug "shashin-wordpress-plugin" and Post to Post Links II error: No post found with slug "shashin-3-development-progress" to see the new features. It’s been a lot of work, and a lot of fun. Many thanks to everyone who helped with testing of the alpha and beta versions.
Please use the comments section of this post for any questions or bug reports. Note if you overlook the notice that tells you to install Post to Post Links II error: No post found with slug "toppa-plugin-libraries-for-wordpress" before upgrading Shashin, and you use WordPress’ automatic plugin upgrade feature, you won’t see Shashin’s warning telling you that Toppa Libraries is missing. So you will need to install the Toppa Libraries, and then de-activate and re-activate Shashin in order to complete the upgrade.
I just did something that’s a no-no with beta software – I added new features. I just couldn’t resist 🙂 . Shashin 3 now works with Twitpic and Youtube. To your right are a photo from Picasa, a photo from my Twitpic account, and a Youtube video I uploaded, all shown using a single Shashin shortcode. Here’s the shortcode:
[shashin type="photo" id="2655,1507,1453" size="small" columns="1" order="user" crop="y" caption="y" position="right"]
If you go to my Post to Post Links II error: No post found with slug "photo-albums", you can see my Twitpic and YouTube feeds now appear as albums, right alongside my Picasa albums.
Albums, photos, and videos from Twitpic, Picasa, and Youtube will all show up in the WordPress post editor’s Shashin media browser, so you can find and add them by point and click (so you don’t need to look up their ID numbers or even type the shortcode).
In your WordPress admin, on the Shashin Tools page, expand the “Examples” section to see how to add Twitpic and Youtube feeds. Youtube doesn’t advertise the existence of their feeds, but they’re there! In addition to a feed for your own account, you can get feeds for their most popular videos, trending videos, top rated, etc and have Shashin automatically update itself daily. So you can do things like feature the current most popular Youtube videos on your site.
Another change I made is photos will now scale to the size you indicate. So if you want the size to be, say, 213 pixels, it’ll be 213 pixels (if it’s not a size available from the photo hosting service, Shashin will find the next largest size available and scale it down). I did this to accommodate showing photos from different services side by side, since they don’t all make their photos available in the same sizes. This also means you can now show album thumbnails in any size, cropped or not cropped (note I changed the size labels to reflect this, so a “large” album thumbnail is now the same size as a “large” photo thumbnail).
You can download the latest version from GitHub. If you already have Shashin 3 beta installed, please 1. deactivate it, 2. delete your current files, 3. upload the new files, and then 4. reactivate (you don’t need to uninstall the plugin – I renamed several files, so this is just to cleanup your Shashin files).
Assuming no major bugs come up in the next few days, I’ll push Shashin 3 to wordpress.org this weekend, and officially retire Shashin 2.
Writing good documentation is hard work 🙂