Thu 19 Jun 2008
While I have written many, many WordPress plugins, I rarely release them in any major way, because I write them for specific one-shot purposes. I’ve always felt that simpler is better, so I write small, simple, easy to use plugins that do one thing and one thing only.
So, I figured I’d solve a minor annoyance with WordPress, and in the process, demonstrate some of the finer points of plugin integration with WordPress. Hopefully, it will demonstrate some new ideas and techniques to plugin authors.
First, let’s link to the plugin itself. The plugin is called Automatic Timezone.
I had the idea for this plugin and wrote it at just around the time that the competition itself was announced, so felt that it was appropriate. And, hey, who knows? I might even win.
So I went back, cleaned it up, and added some key features that I think all plugin authors should see. Read on if you’re a plugin author…
The idea of the plugin is a simple one. The choice of timezone on the Settings->General page is lacking in two main respects:
- It measures in UTC increments (meaning that you have to figure out your own offset)
- It does not take Daylight Savings into account (meaning that most people have to change it twice a year)
PHP can do better than this.
The Automatic Timezone plugin gives you a new settings menu called, simply, Timezone. On this menu, you can pick your timezone using the zoneinfo standard method (pick the nearest city that shares your timezone rules), and let the plugin do the work of figuring everything else out. It will even figure out the daylight savings time and tell you when the next one is coming up!
In fact, one screen shot of the plugin’s configuration page summarizes all the functionality that it has:
Now then, what’s special about it? Well, for plugin authors, I used a few techniques in the plugin that might give them some new ideas for their own plugins.
First, this plugin has some special requirements. Mainly, it needs PHP 5, or PHP 4 in some special cases, in order to get a list of zoneinfo timezones. Since it doesn’t work on all systems, it seems logical that it should refuse to activate on those systems. Nothing is worse than installing a plugin and trying to use it only to find that it doesn’t work.
So, that’s exactly what it does. If you examine the timezone_activation_check function, you’ll see just how it does it. When the plugin is activated, it checks to see if it can find a list of timezones. If it cannot find one, then it self-deactivates, and presents the user with an error stating that it won’t work on their system.
Settings screen modification
Since this plugin replaces a built in function of WordPress, it makes sense that it should remove that built in setting. However, WordPress doesn’t have enough hooks to quite do that. And anyway, we don’t really want to. It might be confusing for users to find settings they are looking for to be missing. In this case, we are going to change a nice little message.
Look on your Settings->General screen. Below the timezone choice is the following message: “Unfortunately, you have to manually update this for Daylight Savings Time. Lame, we know, but will be fixed in the future.” Well, since we’re fixing this right now, let’s change that message.
If you examine the timezone_alter_settings_general function in the plugin, you’ll see how it’s done. What’s more, it will only change that message when the plugin itself is actually in operation and working properly.
While this is not a particularly new technique, it does demonstrate something that some people might not know. You can override any option in WordPress through the use of on-the-fly filters.
I use on-the-fly here because the method does not have an official name, as such. Deep in the heart of WordPress, there’s some code in the get_option function that makes a filter called “pre_option_”+ the name of the option. So, if we want to override that option’s value and replace it with our own, we can simply take the option name, append “pre_option_” to it, and add the filter. In this plugin’s case, it’s overriding the gmt_offset option using the pre_option_gmt_offset filter. Examine the timezone_override_offset function to see how.
The point is that the option name itself is part of the filter hook, so you can filter any option in this way. There’s other cases where the name of the hook is somewhat variable, and you can hook onto most things coming to or from the database in someway.
I also liberally sprinkled PHPDoc type comments throughout the code and tried to add explanatory comments throughout.
These are just a few small techniques that add that extra bit of integration to a plugin, and all plugin authors should think about how you can use methods like these to make your plugin more refined and generally cleaner all around. Anticipate issues and solve them in advance. Hey, it saves you from getting lots of support requests as well.
- Otto, moderator, WordPress.org support forums.