Starting a community wiki to collect up objective best practices for plugin development. This question was inspired by @EAMann's comments on wp-hackers.

The idea is to collaborate on what objective best practices might be so that we can potentially eventually use them in some community collaboration review process.

UPDATE: After seeing the first few responses it becomes clear that we need to have only one idea/suggestion/best-practice per answer and people should review the list to ensure there are no duplicates before posting.

  • I really don't understand how community wiki should work on this (and the others) with SE properly, but maybe that's a question on meta. It will only pile up mostly dupes in answers.
    – hakre
    Aug 23, 2010 at 11:57
  • @hakre: Great point. After seeing thing I'm going to add to the description that people should add only one idea per "answer" and I'm going to change my existing answer to be multiple answers. Aug 23, 2010 at 16:21
  • Related Read: Top 10 Most Common Mistakes in Wordpress Plugins
    – Sisir
    Dec 4, 2013 at 10:01

36 Answers 36


Use Proper Names

Name hooks and filters (classes, functions and vars), so that people can identify them in even a year, when they don't remember any more, where that piece of cake or code comes from. It doesn't matter if hook/filter names get long. Ex. youruniquename_hook/filter_whatitdoes.

  • If your file contains a class named "dbdbInit", then the file that contains the class should be named "dbdbInit.class.php".
  • If you got inside your dbdbInit-class a function that registers ex. custom_post_types, then call it register_custom_post_types().
  • If you got an array that contains the names for custom_post_types, then call the variable where the array is assigned $custom_post_type_names.
  • If you got a function that handles an array write function array_handler( $array ) { // handle the array}..
  • Just try to name things in a way that you know what the sign does/where it belongs to by it's name.

Another thing: If you have to debug stuff then, in 99% of all cases, you get all your messages for not only your code, but for wordpress too. So try to use the same prefix ex. "dbdb" for your classes, public functions and variables/objects. This way you can find them easily between hundreds of files. (Wordpress loads 64 files before your theme and about 1,550 functions, not talking about hooks and filters.)

  • I really have no clear idea what this means. It's first sentence is not a complete sentence. This needs to be rewritten and clarified. Aug 25, 2010 at 20:02
  • 2
    sticking to the WP standards when naming files and functions is also nice, e.g. "class-db-init.php" codex.wordpress.org/WordPress_Coding_Standards
    – gabrielk
    Jun 21, 2011 at 16:29

Use WordPress's Coding Standards


You know how much easier it is to update code you've worked on vs. code someone else has put together? Coding standards make it easier for any developer working on a project to come in and see what's going on.

We know your plugin or theme is your own, and the way you break your lines and add your curly braces is an expression of your individuality. Every indent is a carefully thought-out statement. But with your custom code, you're contributing to WordPress, even if your code isn't in the core application. Coding standards help developers quickly get up-to-speed with your code.


Care about future WordPress & theme versions

Note: After re-reading this advice, I now step back from this practice as checking every function for existence may slow down your site.

Check if functions are deprecated directly in your theme.

This is a "could be like that" example.

if ( ! function_exists( 'wp_some_fn' ) ) 
    $theme_data = wp_get_theme();
    $error = new WP_Error( 'wp_some_fn', sprintf( __( 'The function %1$s is deprecated. Please inform the author', TEXTDOMAIN ), "Theme: {$theme_data->Name}: Version {$theme_data->Version}" );

    // abort
    if ( is_wp_error( $error ) )
        return print $error->get_error_message();
// else if no error - the function works and exists

For proper/best practice error handling see this answer: link

You could drop even the $cause into the function. This will help you and your users to keep on track with functions or classes in your theme that might change.


Use wp options for plugin output strings

In order to make the plugin easily used and customizable, all the output strings should be modifiable. The best way to do that is use wp-options to store the output strings and provide backend to change the default values. Plugin shouldn't use displayed strings that cannot be easily changed using the plugin backend.

For example: Sociable - gives you the ability to change the sentence that appears before the icons part "share and enjoy:"

  • What exactly is a "plugin string?" Can you give use-case examples? Also, please write in complete sentences so this can be a more valuable resource. Aug 25, 2010 at 20:06
  • If you have internationalisation, this should be redundant.
    – Raphael
    Nov 15, 2010 at 11:29
  • I disagree. It makes it easier for end users, but harder for developers. As Raphael said, i18n should be used instead.
    – scribu
    Jan 6, 2011 at 21:09
  • I second Raphael and scribu. gettext functions are easy to filter, there is no need to redundantly store textual content in database.
    – Rarst
    Jan 10, 2011 at 7:42

Decouple from WordPress core code

A Plugin should reduce the impact of the WordPress API to the needed minimum so to seperate plugin code from WordPress code. This reduces the impact of changes within the WordPress codebase on the plugin. Additionally this improves the cross-version compatibility of your plugin code.

This does not mean to not use WordPress functions (use them, as Re-Use existing functions suggests), but not to mesh your code with WordPress functions too much but to seperate your plugins business logic from WordPress functionality.

  • I'm strugglying with the wording on this. Do you mean that a plugin should use the WordPress API whenever possible rather than directly accessing SQL tables and/or directly accessing global variables? Aug 25, 2010 at 19:41
  • Well. Once we had to deal with form data in a project, so to access $_REQUEST. Then they changed the slashing inside that. So instead of using $_REQUEST, use a function that has a single call to $_REQUEST for the whole plugin. In case slashing changes, only this function needs to be changed. This is not against using Wordpress API but to make the plugin decouple to it so you can better react to changes in WP core. This helps to maintain your plugins in the long run. For just some gadget, this is not necessary.
    – hakre
    Aug 25, 2010 at 20:10
  • 3
    Having been a developer on and off for 23 years I've seen many cycles and many suggested best practices come and go. I've seen the pendulum swing wide both ways. I now believe in moderation. In my earlier years I abstracted everything but I learned that abstraction adds complexity that is often worse than the expected benefit. When we see something that causes us trouble as people we immediately seize upon ways to protect ourselves from it in the future but often the medicine is more harmful than the disease. In the USA Sarbanes-Oxley is an example of this. Aug 26, 2010 at 7:01
  • I used to believe global variables were just bad. And then I worked with WordPress and you know what, they have their benefits when used in moderation. I could write a book on this subject (though I don't plan on it; too much work for too little reward.) Where do I see the pendulum now? Simplicity has the highest value. It's probably better not to abstract and then just solve the problems when and if they arise rather than spinning many more cycles in fear that they might. So I'm inclined to vote this one down. Aug 26, 2010 at 7:04
  • 2
    Just from a short question i asked on wp-hackers: They hate you if you use global variables like $wp_taxonomies, because they are "internal" (i know there are some that should be used like $wp_query or $post)...
    – kaiser
    Feb 16, 2011 at 10:12

Use uninstall, activate and deactivate hooks

There are three different hooks for this:

  • Uninstall register_uninstall_hook();
  • Deactivation register_deactivation_hook();
  • Activation register_activation_hook();

A detailed instruction with a working example can be found here..


Not the answer you're looking for? Browse other questions tagged or ask your own question.