I recently read a tutorial on digwp.com, a site run by Chris Coyier and Jeff Starr, and noticed that the functions were called rather generic names, such as custom_css_hooks, save_custom_css, and insert_custom_css.
I sent a message to Chris via Twitter: “It’d be nice to see digwp.com prefix functions used in tutorials. Promote best practices instead of condoning bad behavior?” He replied, asking for more information. When I began to write an email to him, I found that there was actually rather little that has been written on the subject, besides two lines in a large Codex page on writing a plugin. I could have sworn I’ve seen other blog posts, but I couldn’t find one — so here is an attempt.
It’s a simple concept. Anything you create in the global namespace has the potential to conflict with a theme, another plugin (including one you wrote), and WordPress core itself. Thus, prefix everything with a unique-enough character set. For example, all functions I write always start with “nacin_”, and I make sure that my functions are unique across all of my plugins. Even when I send a code snippet over the wp-hackers mailing list, I use nacin_ or myplugin_.
I would recommend the same to digwp.com — use digwp_ as a prefix, and try for them to be unique across all tutorials (within reason, of course). It promotes best practices and prevents accidentally teaching bad behavior. Their goal is to be a resource for plugin developers — many tutorials supply code snippets with the intent that they are studied, reused, and refactored. If two developers use code from a tutorial and decline to rename the functions, their plugins will be incompatible with each other.
Functions are only the beginning. One trick is to use a class to encapsulate your functions as class methods instead. When initializing your class, if you wish to assign it to a global variable, make sure that is unique too. Here are some examples:
function nacin_custom_css_meta_box() {
// ...
}
function nacin_custom_css_save() {
// ...
}
Using a class, a preferred method by many (myself included):
class nacin_custom_css {
function init() {
// ...
}
function save() {
// ...
}
}
$nacin_custom_css = new nacin_custom_css();
Clearly, the class method is very clean. You can name methods after after hooks and action verbs, working within that namespace as if it is a blank slate (because it is). Classes are very helpful in WordPress plugins even if you are not using object-oriented concepts.
At one plugin competition (I would say it was WordCamp NYC 2009, but I can’t find a link) referenced by Ozh Richard in the comments, multiple plugins by the same author could not even be run on the same blog, since they conflicted with each other. Don’t do that. If you have the same function in two different plugins, consider wrapping both in a function_exists check, that way both plugins can use whichever is defined first. Some do that with every function or class they define, just as a precaution. Fatal core errors from redefinition of functions will take a blog down real quick.
Prefix Everything
With custom post types getting super-charged in WordPress 3.0, along with better support for custom taxonomies, more plugins are going to be creating strings that sit alongside one another in the database. If they conflict, the results can be quite unexpected.
So, here’s a thought — prefix everything. Instead of creating an “event” or “twitter” post type, create “nacin_event” or “nacin_twitter” instead. Same with taxonomies. Meta box identifiers. Widget identifiers. Slugs on menu pages and subpages. Any callback or identifier you need to use, make sure you have it properly namespaced.
(Edit:) In the comments, Dougal Campbell also brought up namespacing options (and a related proposal). Though I neglected it in my laundry list, that is also very important. Same goes for transients, as well as metadata for users, posts, comments, and networks. You can also take advantage of serialization in these cases, and store arrays of options together, instead of polluting the options table (and increasing queries in some cases).
This all applies to themes, too — Twenty Ten uses the twentyten_ prefix throughout, for both functions it uses, and action hooks it adds in the theme. We also wrap most in a function_exists check, but that’s actually to allow those functions to be replaced by a child theme.
Use Common Sense
Above all, just make sure you avoid things that look too generic. Google recently released a plugin that prefixed every function throughout, except one — the callback tied to the activation hook. The function name? install()
. I died a little that day.
Of course, if every other plugin author is properly prefixing their functions, then that function won’t conflict with any of them. I would leave the lack of a prefix to core — only some of our functions use the wp_ prefix. And, of course, avoid the wp_ prefix.
This isn’t just theoretical. We broke a plugin in 3.0, as a plugin was defining a function called get_admin_url(), which we added. That’s way too generic a name to assume we won’t add one like it — we’re at 4,000 functions and counting in WordPress. (I sent them an email and they said they would release an update — we try to play nice too. We’ve also renamed a function we had introduced, because it conflicted with a BuddyPress function.)
Another plugin is the Publish2 plugin, which uses publish2_ and p2_ interchangeably. Normally that might be fine, but there’s also the wildly popular P2 theme from Automattic, and the theme also uses p2_. I’m not aware of a naming conflict yet between them, but on the safe side, I sent a message to the Publish2 plugin developer giving him a heads up and suggesting that he standardize on publish2_.
In some ways, it’s about future-proofing. The bigger picture is that your plugin should do one thing and do it well, and allow other plugins to work with it side by side. When you’re a small fish in a big ecosystem, realize you’re not alone and play nice with others.