How To Improve WordPress Plugins

Icon for Menu

Icon for Menu


With the upcoming WordPress release version 2.7 the menu changes to the vertical. This offers several features to the author which we already mentioned in some other posts. But this time I explicitly address Plugin authors and ask them to make their Plugins more user friendly in terms of usability. I will show only two tiny features.
Each of them have been discussed several times on the wp-hacker-mailing-list, but nearly everybody considers them as big improvements to usability.

Adding icons to the menu

My first tip is how to add an icon in the Plugin menu. This is not just a great eye-catcher, but will also make the menu link more obvious and lead to an increase of usability. I won't use a link to some file for the icon this time, instead I will store the icon as a base64-encoded string inside of the Plugin's code. The encoded string doesn't save me just the file or a folder, besides there is no access and no request done for the image, which in the end saves some time, when rendering this page.

I provide a little Service for anyone who doesn't want to write the converter for the image himself. You can easily use my Image2Base64 Generator for this purpose.

The icon will only appear in version 2.7 or above, which can be checked with a simple query. You can get some additional information from the comments inside the code.

/**
 * Images/ Icons in base64-encoding
 * @use function fb_sayfa_sayac_get_resource_url() for display
 */
if( isset($_GET['resource']) && !empty($_GET['resource'])) {
	# base64 encoding
	$resources = array(
		'ssprc.gif' =>
		'R0lGODlhCwALAKIEANTU1Kurq/b29pSUlP///wAAAAAAAAAAAC'.
		'H5BAEAAAQALAAAAAALAAsAAAMlSKoRMysGIZ50A1RJ3ybNow3f'.
		'VJGoQo4nRJDdpwqjtcDy/dhLAgA7'.
		'');
	
	if(array_key_exists($_GET['resource'], $resources)) {

		$content = base64_decode($resources[ $_GET['resource'] ]);

		$lastMod = filemtime(__FILE__);
		$client = ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false );
		// Checking if the client is validating his cache and if it is current.
		if (isset($client) && (strtotime($client) == $lastMod)) {
			// Client's cache IS current, so we just respond '304 Not Modified'.
			header('Last-Modified: '.gmdate('D, d M Y H:i:s', $lastMod).' GMT', true, 304);
			exit;
		} else {
			// Image not cached or cache outdated, we respond '200 OK' and output the image.
			header('Last-Modified: '.gmdate('D, d M Y H:i:s', $lastMod).' GMT', true, 200);
			header('Content-Length: '.strlen($content));
			header('Content-Type: image/' . substr(strrchr($_GET['resource'], '.'), 1) );
			echo $content;
			exit;
		}
	}
}


/**
 * Display Images/ Icons in base64-encoding
 * @return $resourceID
 */
function fb_sayfa_sayac_get_resource_url($resourceID) {
	
	return trailingslashit( get_bloginfo('url') ) . '?resource=' . $resourceID;
}


/**
 * add menu in backend
 */
function fb_sayfa_sayac_add_menu() {
	global $wp_version;
	if ( current_user_can('edit_posts') && function_exists('add_submenu_page') ) {

		$menutitle = '';
		if ( version_compare( $wp_version, '2.6.999', '>' ) ) {
			$menutitle = '<img src="' . wpag_get_resource_url('ssprc.gif') . '" alt="" />' . ' ';
		}
		$menutitle .= __('Post Read Counter', 'sayfasayacprc');
		
		add_submenu_page('index.php', __('Sayfa Sayac - Post Read Counter', 'sayfasayacprc'), $menutitle, 9, __FILE__, 'fb_sayfa_sayac_statistic');
		$plugin = plugin_basename(__FILE__); 
		add_filter( 'plugin_action_links_' . $plugin, 'fb_sayfa_sayac_plugin_actions' );
	}
}

I append an additional space to the the img tag, so it's not touching the menu text. You can also achieve this with a CSS style, but this will most likely be an inline style, which is unnecessary code and the performance will suffer a little bit in your backend. I have been talking about this to the WordPress developers for some time and maybe we will get the CSS definitions with 2.7.

Direct link to "Settings"

Settings links

Settings links

If you read the code above carefully, you probably noticed the use of the filter plugin_action_links. I use this filter to add a "Settings" link. This makes it easier for the user to find the settings page of your Plugin. Mostly the user has to search for the settings page of your Plugin, this can be a real time saver. In my screenshot you can see that I always put the "Settings" leftmost to the standard links "Deactivate" and "Edit".

/**
 * Adds an action link to the Plugins page
 */
function fb_sayfa_sayac_plugin_actions($links) {

	$settings_link = '<a href="sayfa_sayac_de.php">' . __('Settings') . '</a>';
	array_unshift( $links, $settings_link );

	return $links;
}

The above function only works in WordPress 2.7 (more Informations form Latz on his post in German) and has been explained in great detail by Latz! If you like to preserve compatibility with previous WordPress versions, you can do it with this snippet:

/**
 * Adds an action link to the Plugins page
 */
function fb_sayfa_sayac_plugin_actions($links, $file){
	static $this_plugin;

	if( !$this_plugin ) $this_plugin = plugin_basename(__FILE__);

	if( $file == $this_plugin ){
		$settings_link = '<a href="index.php?page=sayfa_sayac/sayfa_sayac_de.php">' . __('Settings') . '</a>';
		$links = array_merge( array($settings_link), $links); // before other links
	}
	return $links;
}

If you have to use this snippet, then the filter has to be used in a different way. You have to replace the code in function fb_sayfa_sayac_add_menu():

$plugin = plugin_basename(__FILE__); 
add_filter( 'plugin_action_links_' . $plugin, 'fb_sayfa_sayac_plugin_actions' );

with this

add_filter( 'plugin_action_links', 'fb_sayfa_sayac_plugin_actions', 10, 2 );

Activate both hooks

I can activate both hooks using the action admin_menu. Beforehand I check if the user is in the admin menu, so the code doesn't get evaluated if he is not.

/* Register WordPress hooks */
if ( is_admin() ) {
	add_action('admin_menu', 'fb_sayfa_sayac_add_menu');
}

I think that these two features really add some extra value for all WordPress users. Besides many Plugins have these features already integrated and I'm sure some more Plugins will get updated soon. Many users have confirmed the better usability, especially with the "Settings" link. Please use our comment area for more ideas, critics and compliments. We appreciate any suggestions you can give.

Comments are closed.

16 comments

  1. Latz

    No English version of my posting? What a pity! OK, here you are: http://elektroelch.de/blog/direct-settings-27/

  2. Frank

    @Latz: i have update, 2 Links now, English and German :)

  3. Twincascos

    The icon in the plugin menu is a great idea. Thanx for the tip.

  4. Alex

    Our pleasure Twincascos :)

  5. Andy Bailey

    I really wish this site had a subscribe by email or was integrated with twitter so I could get notified of new posts. this is just the kind of wordpress geekery that I love to read about!

    are you twittering?

  6. Alex

    Hey Andy,

    we just created a twitter account, so if you like you can follow us there :)

    http://twitter.com/wpengineer

    Subscribe by email will come soon, even though it is not that geekery ;)

    Thanks for the suggestions!

  7. Andy Bailey

    I just followed you on twitter, your first one! will you be integrating it to the blog so it posts a tweet for new posts when they're published?

  8. Alex

    That's exactly what we do, we just have to write the next post ;)

  9. Andy Bailey

    ah ok, sorry, I am hungry for more stuff like this article!

  10. Alex

    Hehehe, that's ok :)

  11. LinkLaunder.com

    Brilliant ideas! Thanks for the information as well as extensive code.

    I will add both to my plugin I'm currently developing. Thanks again...

  12. Alex

    Hey Linklaunder, let us know when you have your plugin ready and what it is about, thanks

  13. LinkLaunder.com

    Hi Alex

    I sure will. In the meantime, I am looking, but cannot find the size of the icon?

  14. LinkLaunder.com

    Nevermind me.. I just installed one of the plugins that I could see use this feature, and checked the size of the image displayed...

    oh, btw: its 11x11px, in case someone else wants to know :-)

  15. Alex

    Glad you found out Linklaunder :) and thanks for telling everybody else.

One pingback

  1. WordPress links - Week 50 2008 | WPStart.org - WordPress themes, plugins and news