If you’re looking to write a WordPress plugin, the best place to go for information is the WordPress codex.
Although you can find a wealth of information in the codex, not everything is covered. Some of the best practices for writing WordPress plugins are developed with experience.
This tutorial will cover some of those minor issues that can help you improve your plugin.
Use do_action(), not function_exists()
A lot of plugins require users to make minor changes to their blog’s theme. Usually those changes manifest themselves as function calls placed in one or more of the theme files.
In the past developers recommended placing the function call in the theme by using code like this.
efd60d102154f6d7b4e05d145b14f2fd011
There is an easier way though, and it’s by using the do_action() function. When you create a function for your plugin that’s meant to be used in the theme, create it like this.
efd60d102154f6d7b4e05d145b14f2fd012
Then tell your users to add this code to their theme files.
efd60d102154f6d7b4e05d145b14f2fd013
That looks a little cleaner than the function exists method, and may not confuse PHP noobs as much. The secret here, is when an action is triggered with the do_action() function, and the callback function doesn’t exists, nothing will happen. That’s what we want. If the person deletes you plugin, we don’t want their site crashing because of a function call in the theme, for a function that doesn’t exists anymore.
Don’t hardcode the plugin directory
Sometimes your plugin needs to know where it lives, or more specifically, the full path to the directory that it’s stored in. I personally find it easy to define a value at the start of the plugin that stores the full path to the plugin’s directory.
efd60d102154f6d7b4e05d145b14f2fd014
ABSPATH is a core WordPress constant that contains the absolute path to the WordPress root directory. There’s a problem with the way I defined my plugin’s absolute path: People might install the plugin in a different directory. Not a directory different than /plugins, but a directory different than /my-plugin.
Even if my ZIP file specifically has the /my-plugin directory, people might change the name of the directory for their own purposes. Maybe they already have a plugin that’s using the same directory name. That’s why you shouldn’t hardcode the plugin’s base directory, and instead you should discover the directory using WordPress’s plugin_basename() function.
efd60d102154f6d7b4e05d145b14f2fd015
The combined use of the dirname() function, and the plugin_basename() function, will give me just the name of the directory my plugin is stored in, within the /plugins directory. So dirname(plugin_basename(__FILE__)) will return ‘my-plugin’.
Now users are free to give my plugin’s directory a different name, and the plugin or blog won’t crash.
Avoid double loading of JavaScript libraries
Your plugin may need to use JavaScript, and you may decide to use a popular library like Prototype, or script.aculo.us.
There’s nothing wrong with that, and I encourage you to use ready made libraries like that, instead of reinventing the wheel.
The only problem with using popular libraries, is your plugin may not be the only plugin activated that uses one of them. In fact, many other plugins could be using them too, and each one of them is trying to include the JavaScript in the document’s <head> section.
To avoid including the library again, which adds bloat to the document, making it take longer to download, consider using a bit of JavaScript like this.
[javascript]
if (!document.getElementsByClassName) {
document.write(’
}
[/javascript]
The method document.getElementsByClassName is a Prototype method. With the above code, I’m checking for it’s existence, which would mean Prototype has already been included in the document. If the method doesn’t exists, I use JavaScript’s document.write() to add a <script> tag to the document, which will include the Prototype library.
With that method, I can be sure I’m not adding Prototype to the document again.
Use classes
PHP has supported classes for a long time now, and you should put them to use in your plugins. The big issue with writing a WordPress plugin, is function name clashing. If you create a function named init(), well there’s a really good chance that another plugin has defined a function with the same name. That’s a problem, and it’ll cause the blog to crash.
The most obvious way to deal with the problem is to prefix your function names with a string that’s unique to your plugin, like this.
efd60d102154f6d7b4e05d145b14f2fd016
That can get old though, especially if your plugin has a lot of functions. Your other option is to use classes to encapsulate your functions, which is the closest thing PHP has to namespaces.
efd60d102154f6d7b4e05d145b14f2fd017
Now you can give you function names anything you want without worrying about name clashes. Just call your functions as static class methods.
Final
Check back here often. I’ll be adding more tips & tricks as I think of them.
November 30th, 1999 at 12:00 am
I would add one more constant: the url to your current plugin directory. This is useful if you have to link to resources such as images stored in the plugin directory:
< ?php
define('MYPLUGIN_URL', get_settings('siteurl') . '/wp-content/plugins/' . dirname(plugin_basename(__FILE__)));
?>
November 30th, 1999 at 12:00 am
Ooops, my php code got stripped out. Here it is:
define(’MYPLUGIN_URL’, get_settings(’siteurl’) . ‘/wp-content/plugins/’ . dirname(plugin_basename(__FILE__)));
November 30th, 1999 at 12:00 am
These are some really great tips. I never even knew the do_action function existed!
November 30th, 1999 at 12:00 am
WOW this is a informative one. thankx . am a newbie to php, still learning C, so this hsould help i guess:)
November 30th, 1999 at 12:00 am
This was extremely helpful — Thank You!
Now I’ll have to go back over a plugin I just made and tighten up the screws a bit! :)
November 30th, 1999 at 12:00 am
Thanks for the tips. I landed here searching for do_action.
How exactly would I use it if I want to pass arguments to the same?
November 30th, 1999 at 12:00 am
Where can I find a document describing all the wordpress functions such as plugin_basename()?
I can’t find a reference to it in the codex at all.
How did you find it???
November 30th, 1999 at 12:00 am
I installed a plugin which called a well-known function which was already loaded by another plugin and caused a problem.Not being a php programmer I didn’t know how to rewrite the code for the new plugin so that it pointed to the already loaded function. Will wrapping it in a class cure the problem?
November 30th, 1999 at 12:00 am
@Don - I sent you an email about that, but for the benefit of other people: I don’t know. :) Many of WP’s core functions aren’t documented. You find out about them through the grape-vine, and by grepping through the WP source code.
November 30th, 1999 at 12:00 am
Just read this page and then another with a solution for avoiding double loading.
http://www.longren.org/2007/02/19/wordpress-and-prototype/