In WordPress, prefix everything

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.

Published by

Andrew Nacin

Lead developer of WordPress, living in Washington, D.C. Follow me on Twitter.

58 thoughts on “In WordPress, prefix everything”

  1. This is one of those things I’d sorted out only after years of development. Mostly after inheriting some POS code I had to clean up, I realized ‘You know, if the variables were named consistently, I wouldn’t be tearing my hair out!’

    If you’re using nacin as your prefix, you don’t always have to use custom (which is generally understood by your prefix). Like I have ipstenu_header to override wp_header and so on. No need to do ipstenu_custom_header since that SHOULD be understood 🙂

    That goes back to the argument of ‘How short can I make a variable and still have it understood…’ though.

    1. But of course. I simply stole “custom_css” from DigWP as a way to contrast the differences. (For reference, the plugin was for custom CSS files for each post.)

  2. Yeah. I always prefixed my variables and functions, but am now realizing the benefits of using classes.

    While non-prefixed functions, etc. annoy me, nothing gets at me like the errors that I see with WP_DEBUG active. And it happens from plugins developed by WP developers I really respect quite a bit (not going to name names, though).

    Look what you’ve done to me…

    😀

  3. Good write-up, I’m really happy to see you mentioning the class method as that’s a naturally safe method, especially with WordPress.

  4. Yup, namespacing is always a good idea. I discussed namespacing for options a few months ago. Same idea, just a more specific area of coding 🙂

    When can find the spare time, I still need to refactor some of my old plugins into classes (a couple of my newer ones are already encapsulated).

  5. From my article about Most Common Coding Mistakes I wrote after reviewing the plugins in last year’s competition:

    Again basics here, but about 40% of the plugins I’ve reviewed use a waaaaay too generic function naming scheme. The point here is to make sure your plugin will never trigger a “Fatal error: Cannot redeclare your poorly named function” error.

    Function names must be two things: descriptive and unique. I’ve found plugins with function named as simply as pretty_title(), pages() or update_options(). Ironically enough, a coder submitted several plugins that won’t be able to run on the same blog because they all use the same function declarations.

    40%, how sad is that? 🙂

  6. I was using prefix for functions’ names for a long time, and I had to create a long names for them. When I start using class in plugin/theme development, I think it’s the best method for avoiding name collision and naming functions. Now I always use classes in my sites, and they work perfectly.

  7. By the way, my PHPXref tells me that the latest version of trunk has:
    4232 function/method names in 4595 definitions and 51720 references.

    Not to mention:
    179 class names in 183 definitions and 1070 references.

  8. After doing a bunch of coding in functions.php files, I started my first plugins recently. I diligently followed the Codex’s advice on my first one (which does NOT tell you to do this!). I was surprised, when I found out this was the way to go.

    Actually, I think it would be really smart if they built this into the process, so it was hard to break OUT of your own little zone. Say, if there was some way that it automatically prefixed everything, wrapped it, and then you had to explicitly UN-wrap it.

    1. I actually made a reference to the Writing a Plugin Codex page. It’s at the bottom, in a list I wish every plugin developer would read, “Plugin Development Suggestions”

      All the functions in your Plugin need to have unique names that are different from functions in the WordPress core, other Plugins, and themes. For that reason, it is a good idea to use a unique function name prefix on all of your Plugin’s functions. Another possibility is to define your Plugin functions inside a class (which also needs to have a unique name).

  9. Thanks for this Article. On my latest plugin (big) – I’ve been reasonably diligent in following this advice, but now I’m about to go back and re-check.

    Hope it works out! Thanks again!

  10. I have been doing this for ages… not only to avoid clashes with other plugins but also with my own code when you copy stuff from one project to another.

    This VERY good advice.

    1. I saw that, thanks Chris!

      The class approach in itself is not PHP5 only. PHP4 does have limited support for object-oriented programming, which includes the ability to use classes.

      That said, the plugin is PHP5 only, because it uses (overuses, really — none of it is necessary) PHP5-only OOP features, specifically abstract classes and static methods. (Not to be confused with static variables, which are allowed in PHP4.) It would be trivial for that plugin to be PHP4-compliant.

      We use classes in core in many locations — they’re the basis for the HTTP, Filesystem, Embeds, Query and Rewrite APIs, among others.

  11. Good article, but I’ll raise you one!

    In your example which had the class nacin_custom_css you followed with a variable assignment for $nacin_custom_css. I’ve seen a lot of cases where variables are created like that but never used. When the variable is not needed simply create the instance on a line by itself (i.e. “new nacin_custom_css();”) without ever assigning a variable and hence without adding the variable name to the global namespace. A use case would be when the only reason for the class is to add actions and filters.

    When you do need a variable and you don’t need multiple instances you could create a static class var and access is like so “nacin_custom_css::$custom_css.” To initializing the value call a static method in your plugin file containing your class declaration. I like to call that function on_load(), i.e.


    nacin_custom_css::on_load();

    Anyway, food for thought.

    1. Ah ha! I actually did cover this, albeit very briefly, by saying, “if you wish to assign it to a global variable.” Point taken, and I agree that the variables are often used when the plugin doesn’t need them.

      That said, I’ll raise you another one. As I mentioned in a reply to a comment of yours on another post just moments ago, hooks enable plugins and themes to play nice with each other, and also enable serious developers and administrators to integrate your plugin exactly how they want it.

      If you don’t assign your class to a global variable, then you are preventing another plugin or a theme from, say, going in and removing a hook that adds some default CSS. Take for example the code required to remove the CSS in the default Recent Comments widget. Now imagine trying to remove a hook without having a reference to the object — quite difficult. (It requires messing with internal globals.)

      For a while, I didn’t bother with the global variable. I’ve since found uses for it, and more importantly, I’ve realized how it can benefit other code running alongside it.

      1. Actually, it’s not true that you need a global variable to enable removal. Actually, if you are using static methods, removal is easier since you don’t have to have a reference to the variable, just do this:


        remove_action('init',array('MyPluginClass','init'));

  12. This is an important topic, thanks for writing this! Developers should make sure they go for a prefix that won’t have collisions of its own, too. Your last name (Nacin) is less common, but for other folks there may be unintended collisions down the line (as in your publish2 / p2 example). The way I’ve gone is to use the class method (mostly for simplicity) and then name the class borrowing from package naming conventions using a domain I own (e.g. http://www.example.com):


    class com_example_custom_css {
    ...
    }

  13. A formidable blog about, I just effortlessly this on the latest associate who had previously been conducting a bit studies for this. And they in all reality bought us breakfast time on the grounds that I uncovered these for regard into your man.. grin. Now allowed me to reword that might: Thnx on the control! Nevertheless this is why Thnkx designed for coughing up plenty of time to take a look at this informational, I find myself enthusiastically regarding it and fancy browsing find out more within the question. Probably, since you grow experience, is it possible you spirit modernizing your web page site with increased facts? Its tremendously a sensible choice for for my situation. Significant thumbs all the way up for that short article!. Take a look at me at Planet Audio Subwoofers

  14. I don’t even know how I ended up here, but I believed this post was once great. I do not recognize who you might be but certainly you are going to a famous blogger should you aren’t already. Cheers!

Comments are closed.