Posts tagged ‘plugin’

In trying to figure out what to talk about at WordCamp Atlanta, I remembered a question put to me in WordCamp Birmingham. The question was how can a theme developer easily make a plugin-dependency in their theme?

I wrote some code to do this sort of thing, just as an example/test/demonstration, but then after looking over the schedule, I found that Thomas Griffin had beat me to it. After looking over his slides and having him walk me through his code, I realized that his solution was much more fully featured than mine, so I’m glad I didn’t present anything on this topic. (I ended up just doing an answer session where I tried to answer any question put to me, and frankly that was much more fun than having slides, so I’m probably just going to do that from now on.)

You can find his cool library here, BTW: http://tgmpluginactivation.com/

However, his solution is highly complex. The class he came up with is well done and fully-featured. He has capabilities for making notifications in the header space on the admin section, lightbox popups, bulk installs, forced activation, custom skinning, etc. It’s a big thing. While that’s great for a lot of people in terms of having code you can just drop-in and use, I thought that it doesn’t do much to teach how one can DIY it.

See, the code I wrote was tiny. It basically just provides some minor functionality to show a theme author how to detect installed plugins, how to detect when they’re active, how to build install and activate links, etc. It doesn’t do any pretty stuff. No custom skinning. No lightbox popups. All these things are possible, but if somebody hands you a hunk of library code to do them, then you know how to use that library, not how it works. I dislike using libraries for this reason.

So here’s the small class I wrote to do the same sort of thing, but in a very bare-bones style.

/* 

Simple class to let themes add dependencies on plugins in ways they might find useful

Example usage:

	$test = new Theme_Plugin_Dependency( 'simple-facebook-connect', 'http://ottopress.com/wordpress-plugins/simple-facebook-connect/' );
	if ( $test->check_active() ) 
		echo 'SFC is installed and activated!';
	else if ( $test->check() ) 
		echo 'SFC is installed, but not activated. <a href="'.$test->activate_link().'">Click here to activate the plugin.</a>';
	else if ( $install_link = $test->install_link() )
		echo 'SFC is not installed. <a href="'.$install_link.'">Click here to install the plugin.</a>';
	else 
		echo 'SFC is not installed and could not be found in the Plugin Directory. Please install this plugin manually.';

*/
if (!class_exists('Theme_Plugin_Dependency')) {
	class Theme_Plugin_Dependency {
		// input information from the theme
		var $slug;
		var $uri;

		// installed plugins and uris of them
		private $plugins; // holds the list of plugins and their info
		private $uris; // holds just the URIs for quick and easy searching

		// both slug and PluginURI are required for checking things
		function __construct( $slug, $uri ) {
			$this->slug = $slug;
			$this->uri = $uri;
			if ( empty( $this->plugins ) ) 
				$this->plugins = get_plugins();
			if ( empty( $this->uris ) ) 
				$this->uris = wp_list_pluck($this->plugins, 'PluginURI');
		}

		// return true if installed, false if not
		function check() {
			return in_array($this->uri, $this->uris);
		}

		// return true if installed and activated, false if not
		function check_active() {
			$plugin_file = $this->get_plugin_file();
			if ($plugin_file) return is_plugin_active($plugin_file);
			return false;
		}

		// gives a link to activate the plugin
		function activate_link() {
			$plugin_file = $this->get_plugin_file();
			if ($plugin_file) return wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin='.$plugin_file), 'activate-plugin_'.$plugin_file);
			return false;
		}

		// return a nonced installation link for the plugin. checks wordpress.org to make sure it's there first.
		function install_link() {
			include_once ABSPATH . 'wp-admin/includes/plugin-install.php';

			$info = plugins_api('plugin_information', array('slug' => $this->slug ));

			if ( is_wp_error( $info ) ) 
				return false; // plugin not available from wordpress.org

			return wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $this->slug), 'install-plugin_' . $this->slug);
		}

		// return array key of plugin if installed, false if not, private because this isn't needed for themes, generally
		private function get_plugin_file() {
			return array_search($this->uri, $this->uris);
		}
	}
}

Obviously, for theme authors wanting to do something, they’re going to want to make much prettier means of displaying things and installing things. Thus, this code is meant as an example, to show the basics of how to detect such things.

So, use it directly if you like (it works), but more importantly, if you want to put plugin dependancies in your theme, then I suggest reading it and figuring out how it works instead. Then you can see how plugins can be detected and how to build simple install and activation links.

(BTW, note that I used the slug and the PluginURI for a reason. Plugins should be using a unique URL for the plugin in their code, and that URL is very likely to be the most unique thing about the plugin, and therefore the best way to check for a plugin already being there or not. Slugs can be duplicated by accident or design, but URLs are generally going to be unique and specific to a particular plugin.)

Shortlink:

Google came out with an experimental specification for websites to provide “hints” on forms, to allow things like autocomplete to work better and be more standardized. Seems useful.

Here’s a quick plugin snippet you can use to make your comments form use this specification. Only Chrome 15 and up is using this at the moment, but in the long run I think most browsers will be implementing something similar to this, since filling out forms is just one of those endless pieces of drudgery that we could all stand to do away with.

Note that your theme will need to be using the comment_form() function call for this to work, otherwise you’ll just have to edit your comment form in the theme manually.

<?php
/*
Plugin Name: Add X-Autocomplete Fields to Comment Form
*/
add_filter('comment_form_default_fields','add_x_autocompletetype');
function add_x_autocompletetype($fields) {
	$fields['author'] = str_replace('<input', '<input x-autocompletetype="name-full"', $fields['author']);
	$fields['email'] = str_replace('<input', '<input x-autocompletetype="email"', $fields['email']);
	return $fields;
}

Simple little bit of code, really. Should work with any theme using the normal comment_form() function call.

Shortlink:

If you read “how-to” stuff for WordPress sites around the web, then you frequently run across what many people like to call “snippets”. Short bits of code or functions to do various things. I myself post snippets frequently, usually made up on the fly to solve somebody’s specific problem.

One question I get a fair amount is “where do I add this code?”

The usual answer to this for a lot of people is “in the theme’s functions.php file”. This is a quick solution, but it is often a problematic one.

The reason this has become the more or less go-to place to add these snippets is because it’s complicated to explain to a newbie how to make a plugin and activate it, or to point out the problems with modifying core code, or plugin code. Saying to look for a specific file in their theme, on the other hand, is quick and easy, and until recently theme upgrades have been fairly rare.

However, as themes get upgrades, it becomes more and more incorrect to tell people to modify them directly. And telling people how to create child themes is complex, even if it’s easy to do.

So I’d like to start a new trend, and recommend that people start making Site-Specific Plugins. Most people who run WP sites on a serious level do this in some way already, but if you make it sorta-standard practice, then it’ll make things simpler all around.

How to create a Site-Specific Plugin

1. Create a new directory in the plugins directory. Name it after the site in some fashion. For example, /wp-content/plugins/example.com or something like that.

2. Create a new php file in that directory. Name is dealer’s choice.

3. Put this in the file:

<?php
/*
Plugin Name: Site Plugin for example.com
Description: Site specific code changes for example.com
*/

4. Finally, go activate your new blank plugin on the site.

Now you have a simple and specific place to add snippets. It will survive upgrades of any sort, and you can edit it to add new code on an as needed basis. What’s more, it’s kinda sorta break-proof. If the user uses the built-in plugin editor to edit it, and they add code that breaks the site, then the editor detects that on saving the code and deactivates the plugin, preventing the “white screen of death” for their site.

This is a much better way to use “snippets” than the theme’s functions.php file, and we should really use it more often in our replies to users.

Shortlink:

My post about how to customize WordPress images with tricks like greyscale and such got me lots of feedback, so I figured I might as well turn it into a plugin.

The ImageFX plugin allows you to customize the image sizes from WordPress or custom ones for your theme, by applying filters to them.

The way it works is basically identical to my original post on the topic, only it allows the filters to be defined on a per-image-size level. It also allows the addition of a “slug” to be appended to the image filename, which is useful for cases where you want to have two images at the same size, but with different filters.

Since it was easy to do, I went ahead and created several other simple image filters that you can use for your images:

  • Greyscale (black and white)
  • Sepia tone (old-timey!)
  • Colorize with red, yellow, green, blue, or purple
  • Photonegative
  • Emboss
  • Brighten
  • Greyscale except red, green, or blue (classy!)

Here’s some examples. This a pic of me, Nacin, Rose, and Matt at WordCamp San Francisco. I ran it through the sepia, blue colorize, and grey-except-red filters.



These are some of the default filters included, but since I could, I went ahead and made it easily expandable too. All you have to do to define a filter is to create a function to do the image filtering you want, then call the imagefx_register_filter() function to add it.

To implement your own custom filter, you can do it like this:

imagefx_register_filter('custom-name','my_custom_filter');
function my_custom_filter(&$image) {
 // modify the $image here as you see fit
}

Note that the $image is passed by reference, so you don’t have to return it. This is because the $image resource takes up a lot of memory, so to save on memory usage, you are manipulating it in place, sort of thing.

You can use any of the image functions in PHP to change the image however you like. The filters I’ve implemented are mostly pretty simple. You can see them all in the filters.php file, in the plugin.

Caveats: The plugin will only filter JPG images, to avoid the overhead of recompressing PNGs and to avoid breaking animated GIF files. Also note that I haven’t tested these filters extensively. They’re only a starting point, sort of thing. I spent all of about 20 minutes writing them, so don’t expect miracles. :)

You can download version 0.1 of the plugin from the WordPress plugin directory: http://wordpress.org/extend/plugins/imagefx/

Enjoy!

Shortlink:

Facebook recently made a breaking change to the developer process, which makes it impossible for new applications to get the correct API keys. Since this essentially broke all previous versions of SFC, I went ahead and pushed the beta version public. It’s still unfinished, but Facebook didn’t really give me a lot of choice.

So, this is a quick walkthrough of some of the new features of SFC 1.0.

Upgrade Process

The upgrade process is slightly more involved for this one. It is recommended that you deactivate the old SFC plugins before upgrading. Why? Well, if you don’t, you’ll get a bunch of errors when visiting the Plugins screen later, saying that all the old SFC plugins either don’t exist or have an invalid header. These errors are normal, because of the next feature:

One plugin only

No more sub-plugins

Simple Facebook Connect is now a single plugin, with modular features. If you examine the plugins screen, you’ll find only one entry: Simple Facebook Connect.

The many-plugins-in-one was a useful experiment, IMO, and I still think it’s a better way to do things. But many people find it confusing, and some have disagreed with the notion. A lack of useful core support for plugin dependencies and user feedback convinced me to switch it up. So now, SFC is one plugin. But it’s still modular!

Sub-module selections

As you can see in the image, you can still turn on and off pieces of the plugin. Why have a piece running and consuming valuable resources if you’re not using it? Turning a module off completely disables it in the code. And the core of SFC itself is still written modularly, for maximum performance (since integrating Facebook itself is such a drag on performance for a site to begin with).

Support for new Facebook code

Over a year ago, Facebook stopped supporting the original Facebook Connect libraries. This was a major problem for sites, however the old code still worked. So as time went on, and the old Connect libraries started to degrade and become less and less useful, SFC was rewritten from the ground up to use all the newer supported libraries. Facebook’s JS SDK is used. FB’s Graph API is used. The old Facebook REST Platform code is completely gone, as are the older incompatible Facebook Connect libraries. OpenGraph meta tags (including embed info for images and video) are inserted into the entire site, completely automatically, allowing Facebook to see the content of your site and act accordingly.

Many of the plugins themselves have been rewritten fairly extensively as well, but with this comes some removal of older code.

Faux Share button settings

The Share button is gone. It was previously implemented using the older Connect libraries, but with the newer libraries from Facebook, it’s been completely removed. There was just no good way to retain it, Facebook has simply dropped any and all support for it. So, in it’s place (because it was so handy) is a modified Like button, which can still look sorta like the old Share button. The SFC module is still named Share, for ease of transition. The Like button itself is still around too, so you can use both Like and Share to get two Like buttons on the same post, perhaps for different placement.

The Bookmark widget is gone. It simply isn’t supported anymore, and didn’t work anyway.

The Find on Facebook widget is gone. This didn’t do really anything special to begin with, other than place the Find Us image into a widget, with a link to the Facebook Page. The image it once used is still included in the plugin, for people that want to do this themselves via a text widget.

The Connect widget is gone, but may make a return in the next version, as soon as some bugs are sorted out.

The Upcoming Events widget is gone. It rarely worked properly to begin with, and the newer XFBML libraries doesn’t have support for it anymore. A alternate approach to this may make it back into the next version.

All the remaining widgets have been combined into a single module for use on the widgets screen. In addition, most of them still have a way to access them directly, such as from a function call in a theme.

Publisher settings

The Publisher has been simplified greatly. For one, auto-publishing now works even for Applications! The confusing permissions dialogs have been reduced to one. Colored indicators have been added, showing when the plugin has the necessary “tokens” from Facebook in order to be able to publish properly. The manual publishing functionality is still on the edit post screens too. And for those people using the auto-publish, a new system for pulling Facebook comments on their published posts back into the blog has been implemented.

For those who wanted it, Custom Post Type support has been added to the publisher as well. Any CPT marked as “public” gets shared like everything else.

Register screen

The Register system has been completely rewritten to take advantage of Facebook’s new register plugin functionality. It can handle standalone registrations, or registrations using Facebook information. It even adds a Facebook created captcha to prevent spam registrations.

Login has been improved. One of the most common complaints was “What does ‘User not recognized’ mean?” This should be severely reduced now, since the Login module will auto-detect existing users and automatically connect their local WP accounts with their FB accounts, when they try to login. This follows Facebook’s own Registration Flow Models for connecting users to sites.

The Comment system has been improved. The share-after-comment system now happens in the background, no extra popups for users to have to click on. The whole system is now using the Graph API, so no more strange javascript errors causing weirdness. Although there is still some javascript to display the user their picture and info after logging in, so it still has that same look and feel.

There’s a lot more too. I’ll be updating this post with new stuff soon!

 

Shortlink:

First, WordPress plugin authors: Please don’t do this.

if ( isset($_GET['resource']) && !empty($_GET['resource']) ) {
	$resources = array(
		'icon1.png' => '... base 64 encoded code ...',
		'icon2.png' => '... base 64 encoded code ...',
		);

	if ( array_key_exists($_GET['resource'], $resources) ) {
		$content = base64_decode($resources[ $_GET['resource'] ]);
                header('Content-Length: '.strlen($content));
                header('Content-Type: image/png');
            	echo $content;
		exit;
	}
}

I’ve seen a few different versions of this, and while the idea is nice, this is really the wrong way to go about it.

The idea is to include small icons or images in the plugin file itself, instead of as separate files. This sort of code then lets you reference them by calling a URL of ?resource=icon1.png or whatever. When that resource variable is detected, the plugin kicks in and serves up the image instead of the site.

Advantages to this sort of thing:

  • No need for extra icon files

Disadvantages to this sort of thing:

  • Now every http request to get an icon file on your admin page results in loading up the WordPress code, causing extra CPU usage.

Here’s a better way. It’s called the Data URI.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

Here’s that code in action, right here: Red dot

Why this is better:

  • Same benefits as before, no need for extra icon files
  • No extra CPU load from loading WordPress to get that icon file
  • No extra HTTP requests at all, in fact, since the data for the tiny icon is contained right there in the code

Disadvantage:

  • Doesn’t work in IE7. You can work around this by detecting IE7 and serving up the image separately, if you really want. Or you can just ignore it like most people do. Seriously. IE7 is insecure (link, link) and nobody should be using it, anywhere. WordPress itself will probably drop IE7 support in the admin in the next couple of versions.

So use Data URIs for small images (under 32KB in size). They’re fast and easy. They’re an idea whose time has come.

Shortlink: