138

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.

3
  • 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
    Commented 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. Commented Aug 23, 2010 at 16:21
  • Related Read: Top 10 Most Common Mistakes in Wordpress Plugins
    – Sisir
    Commented Dec 4, 2013 at 10:01

36 Answers 36

74

Use Actions and Filters

If you think people would like to add or alter some data: provide apply_filters() before returning.

P.S. One thing I find a bit disappointing and that your question addresses is the percentage of plugins that are designed only for end-users, i.e. that have no hooks of their own. Imagine if WordPress were designed like most plugins? It would be inflexible and a very niche solution.

Maybe things would be different if WordPress were to have the ability to auto-install plugins on which other plugins depended? As it is I typically have to write a lot of the functionality I need from scratch because clients want things a certain way and the available plugins, while 90% there, don't allow me the flexibility to update the remaining 10%.

I really do wish those leading the WordPress community would identify a way to ensure that plugins are rewarded for following best practices (such as adding in hooks for other developers) much like good answers are rewarded on a StackExchange site.

Let's take an example from another question:

Example: I want to do something in my plugin when someone retweets an article. If there was a custom hook in whatever the popular retweet plugin is that I could hook in to and fire off of, that would be great. There isn't, so I can modify their plugin to include it, but that only works for my copy, and I don't want to try to redistribute that.

Related

0
55

Load Scripts/CSS with wp_enqueue_script and wp_enqueue_style

Plugins should not load / attempt to load duplicate versions of JS / CSS files, especially jQuery and other JS files included in WP Core.

Plugins should always use wp_enqueue_script and wp_enqueue_style when linking JS and CSS files and never directly via <script> tags.

Related

3
  • 1
    Suggestion: Might be worth sticking a small note about using dependancies in there to(since it's part of the enqueue system).
    – t31os
    Commented Feb 17, 2011 at 18:26
  • Right, but better is that you register the styles and scripts before and then enqueue this scripts via ID. This is very fine for other developers to change the scripts or use it in custom plugins. Its also easier to change the order or create a summery file.
    – bueltge
    Commented Sep 19, 2012 at 21:35
  • 2
    plus, Load scripts and styles on pages where required. scribu.net/wordpress/optimal-script-loading.html
    – M-R
    Commented Dec 12, 2012 at 9:38
50

I18n support

All output strings should be linked to an appropriate text domain to allow for internationalization by interested parties, even if the developer has no interest in translating their own plug-in.

Note that it is very important to load the language files during the init action so the user can hook into the action.

See the Codex: I18n for WordPress Developers

And also this article: Loading WP language files the correctly.

Since WordPress 4.6+

WP 4.6 changed the load order and the locations checked, it has made it a lot easier for developers and users.

Considering a plugin with a textdomain 'my-plugin', WordPress will now FIRST look for a translation file in:
/wp-content/languages/plugins/my-plugin-en_US.mo

If it fails to find one there it will then look for one where the plugin tells it to look (usualy in the pluigns 'language' folder if following the codex):
/wp-content/plugins/my-plugin/languages/my-plugin-en_US.mo

Lastly if no language file is found it will check the default location of:
/wp-content/languages/my-plugin-en_US.mo

The first check was added in 4.6 and gives users a defined place to add a language file, as before they would need to know where the developer added the language file, now the user just needs to know the plugin's textdomain: /wp-content/languages/plugins/TEXTDOMAIN-LOCAL.mo


Below is the old way (Not relevant since WP 4.6+)

[...]
Finally, I would like to point out that is important to load custom user language files from WP_LANG_DIR before you load the language files that ship with the plugin. When multiple mo-files are loaded for the same domain, the first found translation will be used. This way the language files provided by the plugin will serve as a fallback for strings not translated by the user.

public function load_plugin_textdomain()
{
    $domain = 'my-plugin';
    // The "plugin_locale" filter is also used in load_plugin_textdomain()
    $locale = apply_filters( 'plugin_locale', get_locale(), $domain );

    load_textdomain( 
            $domain, 
            WP_LANG_DIR . '/my-plugin/' . $domain . '-' . $locale . '.mo' 
    );
    load_plugin_textdomain( 
            $domain, 
            FALSE, 
            dirname( plugin_basename(__FILE__) ) . '/languages/' 
    );
}
2
  • For me the most important one. It is not much of extra work to do it but one of the things you can make your plugin more useful for the millions of users who don't speak english as their first language. You don't even have to translate any word yourself, but prepare everything to be translated.
    – 2ndkauboy
    Commented Aug 29, 2010 at 20:23
  • This is such a valuable, yet easy thing to do to, just wanted to say i agree and every plugin author should be doing this.
    – t31os
    Commented Feb 17, 2011 at 18:23
48

Ensure Plugins Generate No Errors with WP_DEBUG

Always test your plugins with WP_DEBUG turned on and ideally have it turned on throughout your development process. A plugin should not throw ANY errors with WP_DEBUG on. This includes deprecated notices and unchecked indexes.

To turn debugging on, edit your wp-config.php file so that the WP_DEBUG constant is set to true. See the Codex on Debug for more details.

4
  • Please see the UPDATE about having only best-practice per answer; can you split into multiple answers? Commented Aug 23, 2010 at 16:36
  • Sure, no problem. Sorry about that. Commented Aug 23, 2010 at 17:02
  • Thanks, and wasn't your oversight, it was mine. I revised the question to ask for one best practice per answer based on @hakre's question about duplicates and how to make this work. Commented Aug 23, 2010 at 18:32
  • 6
    If I could upvote this answer twice, I would. It's so frustrating when I'm working on a dev site and have to turn WP_DEBUG off because a plugin I need to use is spewing warnings and notices all over the place.
    – Ian Dunn
    Commented Aug 28, 2012 at 16:04
42

First Use Existing Functions in WordPress Core

If you can: use existing functions included in WordPress core instead of writing your own. Only develop custom PHP functions when there is not an appropriate pre-existing function in WordPress core.

One benefit is you can use "log deprecated notices" to easily monitor functions that should be replaced. Another benefit is users can view the function documentation in the Codex and better understand what the plugin does even if they are not an experienced PHP developer.

Related

5
  • One of the biggest problems here is learning that an appropriate existing function exists. What would be useful would be a place to post code and/or functionality needs to enable to community to comment on which function to best use. Maybe StackExchange could be used for this? Commented Aug 25, 2010 at 20:20
  • Puh. That would be pretty hard and i guess some sort of endless task. I think extending the codex in this way would be best, because it already exists.
    – kaiser
    Commented Aug 27, 2010 at 6:53
  • I guess extending the codex and maybe linking from there to related stockexchange threads would be good enough.
    – kaiser
    Commented Aug 27, 2010 at 23:49
  • 4
    A problem with that is that a lot of core isn't really structurally designed for reusability. I just had to copy and slightly modify half the image manipulation/metadata functions to create my own attachment-like behaving post-type, just because a function like downsize() calls some function that includes a hardcoded check for post-type='attachment'. There's lots of that like the inflexible wp_count_posts() being another example. Before you can really reuse core WP needs a complete refactoring.
    – wyrfel
    Commented Feb 16, 2011 at 10:04
  • Completely agree on this. My all time favorite example: wp-login.php. So, "If you can" was a good starter for the answer...
    – kaiser
    Commented Feb 16, 2011 at 10:08
35

Uninstalling should remove all of a plugin's data

Upon being removed from a WordPress installation, a plugin should delete all files, folders, database entries, and tables which it created as well as the option values it created.

Plugins may offer an option to export/import settings, so that settings can be saved outside of WordPress prior to deletion.

Related

11
  • 4
    This should be the default behavior, yes, but it should also prompt the user to keep some data ... like when uninstalling a video game asks you if you want to remove saved games and downloaded material. A user might only be deactivating the plug-in for testing purposes and wouldn't want to go back through setting up their options when they reactivate it.
    – EAMann
    Commented Aug 23, 2010 at 14:24
  • 1
    I'm only talking about when a plugin is completely removed, not when it is deactivated. Commented Aug 23, 2010 at 16:33
  • 2
    I understand that ... but sometimes I'll delete plug-ins so I can manually re-add them from a backup or beta version that's not yet hosted in the repository ...
    – EAMann
    Commented Aug 23, 2010 at 18:29
  • 4
    @EAMann: For that and for migrating plugins to another server, a plugin should provide a mechanism to export and import settings.
    – hakre
    Commented Aug 24, 2010 at 9:18
  • 2
    I've seen a few plugins offer an "Uninstall" button in their settings with big red warnings it will delete all data. This is separate from de-activation, and I think a great way to handle it. Not everyone uses the "Delete" button to remove a plugin.
    – gabrielk
    Commented Jun 21, 2011 at 16:20
34

Prevent SQL Injection with Input Data

A plugin should sanitize all user input retrieved directly or indirectly (e.g. via $_POST or $_GET) before using input values to query the MySQL database.

See: Formatting SQL statements.

1
  • 5
    You should also sanitize data coming out of the database. Basically, never trust any data that isn't hardcoded. codex.wordpress.org/Data_Validation is a good reference too.
    – Ian Dunn
    Commented Jun 20, 2011 at 22:57
31

Prefix All Global Namespace Items

A plugin should properly prefix ALL global namespace items (constants, functions, classes, variables, even things like custom taxonomies, post types, widgets, etc.). For example, do not create a function called init(); instead, name it something like jpb_init().

Its common should use a three or four letter prefix in front of names or to make use of the PHP Namespace Feature. Compare: Single-letter prefix for PHP class constants?

Related

1
  • I would use global functions very sparingly, even when prefixed. Instead use classes with a namespace. If you want to have utility/template functions you can use a static function within a class.
    – Husky
    Commented Sep 1, 2022 at 10:21
31

Use a class and object-oriented PHP code

There's no reason not to write clean, object-oriented PHP code. PHP4 is not supported since 2008. Of course, you can prefix all your function names to end up with endlessly_long_function_names_with_lots_of_underscores, but it's much easier to just write a simple class and bundle everything in that. Also, put your class in a separate file and name it accordingly so you can easily extend and maintain it:

// in functions.php
require 'inc/class-my-cool-plugin.php';
new MyCoolPlugin();

// in inc/class-my-cool-plugin.php
class MyCoolPlugin {
    function __construct() {
        // add filter hooks, wp_enqueue_script, etc.
        
        // To assign a method from your class to a WP 
        // function do something like this
        add_action('admin_menu', [$this, "admin"]);
    }
    
    public function admin() {
        // public methods, for use outside of the class
        // Note that methods used in other WP functions 
        // (such as add_action) should be public
    }
    
    private function somethingelse() {
        // methods you only use inside this class
    }
}
7
  • dont use new MyCoolPlugin(); i think is better you hook in WP via Hook: plugins_loaded
    – bueltge
    Commented Oct 15, 2010 at 12:54
  • Not sure about that. According to the codex plugins_loaded is one of the very first things loaded, so i think it makes little difference to either do a construct like this, or add it as an action.
    – Husky
    Commented Oct 15, 2010 at 21:07
  • 5
    it is just one of those best practices that make it nicer for everyone. Commented Oct 19, 2010 at 2:01
  • 1
    As far as I can see adding a hook into plugins_loaded makes zero improvements, and wouldn't be a best practice since there isn't any improvements, if anything there are is increase memory usage, decreased speed as it has to go through an action instead of the actions just being added. Also using OO shouldn't be considered a best practice.
    – Backie
    Commented Feb 16, 2011 at 10:46
  • 4
    @IanDunn: if you want PHP4 support, but PHP4 support has been dropped since 2008, over 4 years ago. There's no reason to still be using PHP4-specific checks.
    – Husky
    Commented Aug 29, 2012 at 13:42
26

Deactivation should not provoke Data-Loss

A plugin should not delete any of its data upon deactivation.

Related

23

Only include files that you need...

If you're in the front end, don't include code that relates to the admin area.

21

Announce Data-Loss on Plugin Uninstallation

Upon uninstallation a plugin should prompt a user that it will be deleting it's data and receive a confirmation that the user is okay with deleting the data before doing so and a plugin should also allow the user the option to keep the data upon uninstallation. (This idea from @EAMann.)

Related

2
  • 3
    Wordpress itselfs displays a warning message in the admin, that this happens (at least in trunk right now).
    – hakre
    Commented Aug 24, 2010 at 9:06
  • Aside from the warning message displayed by WordPress, it is impossible for the plugin to prompt the user, since at the time of uninstallation it is already deactivated. But see ticket #20578.
    – J.D.
    Commented Mar 20, 2015 at 13:00
19

Minimize Names Added to the Global Namespace

A plugin should reduce it's impact as much as possible by minimizing the number of names it adds to the global namespace.

This can be done by encapsulating the plugin's functions into a class or by using the PHP namespaces feature. Prefixing everything can help as well but is not that flexible.

Next to functions and classes, a plugin should not introduce global variables. Using classes normally obsoletes them and it simplifies plugin maintenance.

Related

1
  • Can you please move the "should not introduce global variables" to it's own answer? That is related by separate from this question and actually one I'd like to debate (both because I think I may disagree is special cases and because I want to learn from the opinions of others.) Commented Aug 25, 2010 at 19:57
19

Let plugin's folder name be changed

/plugins/pluginname/{various}

The "pluginname" used for the folder should always be changeable.

This is normally handled by defining constants and consistantly using them throughout the plugin.

Needless to say many popular plugins are sinners.

Related:

  • plugins_url() for easy linking to resources, included with plugin.
3
  • Renaming the plugin's folder will cause automated updates to break, so I'm not sure it's the best thing to be doing.
    – mtekk
    Commented Jan 14, 2011 at 5:53
  • You'd have to re-enable the plugin after doing the change anyway(the name change would likely result in plugin deactivation), at which point WP will re-create or update the appropriate DB entries related to plugins(so it wouldn't break updates at all).
    – t31os
    Commented Feb 17, 2011 at 18:34
  • Instead of using a constant, use plugin_basename(__FILE__) to figure the plugin's local name out. That is useful for having copies of the same plugin (testing, multiple accounts elsewhere but only one per plugin, ...), too.
    – Raphael
    Commented Mar 11, 2011 at 22:23
19

Use WordPress (built in) Error handling

Don't just return; if some user input was wrong. Deliver them some information about was was done wrong.

function some_example_fn( $args = array() ) 
{
    // If value was not set, build an error message
    if ( ! isset( $args['some_value'] ) )
        $error = new WP_Error( 'some_value', sprintf( __( 'You have forgotten to specify the %1$s for your function. %2$s Error triggered inside %3$s on line %4$s.', TEXTDOMAIN ), '$args[\'some_value\']', "\n", __FILE__, __LINE__ ) );

    // die & print error message & code - for admins only!
    if ( isset( $error ) && is_wp_error( $error ) && current_user_can( 'manage_options' ) ) 
        wp_die( $error->get_error_code(), 'Theme Error: Missing Argument' );

    // Elseif no error was triggered continue...
}

One error (object) for all

You can set up a global error object for your theme or plugin during the bootstrap:

function bootstrap_the_theme()
{
    global $prefix_error, $prefix_theme_name;
    // Take the theme name as error ID:
    $theme_data = wp_get_theme();
    $prefix_theme_name = $theme_data->Name;
    $prefix_error = new WP_Error( $theme_data->Name );

    include // whatever, etc...
}
add_action( 'after_setup_theme', 'bootstrap_the_theme' );

Later you can add unlimited Errors on demand:

function some_theme_fn( $args )
{
    global $prefix_error, $prefix_theme_name;
    $theme_data = wp_get_theme();
    if ( ! $args['whatever'] && current_user_can( 'manage_options' ) ) // some required value not set
        $prefix_error->add( $prefix_theme_name, sprintf( 'The function %1$s needs the argument %2$s set.', __FUNCTION__, '$args[\'whatever\']' ) );

    // continue function...
}

Then you can fetch them all at the end of your theme. This way you don't interrupt rendering the page and can still output all your errors for developing

function dump_theme_errors()
{
    global $prefix_error, $prefix_theme_name;

    // Not an admin? OR: No error(s)?
    if ( ! current_user_can( 'manage_options' ) ! is_wp_error( $prefix_error ) )
        return;

    $theme_errors = $prefix_error->get_error_messages( $prefix_theme_name );
    echo '<h3>Theme Errors</h3>';
    foreach ( $theme_errors as $error )
        echo "{$error}\n";
}
add_action( 'shutdown', 'dump_theme_errors' );

You can find further information at this Q. A related ticket to fix the "working together" of WP_Error and wp_die() is linked from there and another ticket will follow. Comments, critics & such is appreciated.

3
  • Why do you instantiate a WP_Error object if you only access it's properties and never pass the instance as an object?
    – ProfK
    Commented Oct 28, 2011 at 6:03
  • @ProfK I reworked it to be shorter and the title/content for wp_die(); was wrong (reversed). About your Q) I don't completely get it. When you set up an instance of the WP_Error class you have full access to its data via functions like get_error_code();, get_error_message();, get_error_data(); and the plural versions. You could also only instantiate it once at the bootstrap of your theme or plugin and simply use $error->add(); to fill other errors and finally output it in the footer with $error->get_error_messages(); to catch them all.
    – kaiser
    Commented Oct 28, 2011 at 11:01
  • @ProfK I'll post future updates to this Q. I'm currently inspecting the behavior of the wp error class and want to write a ticket about a public theme error API (draft already done). You'll find a link to another ticket that brings WP_Error and wp_die() closer together (already has a patch) at the bottom of the Q. Any comment, suggestions, critics and else is highly appreciated.
    – kaiser
    Commented Oct 28, 2011 at 18:00
17

Comment using PhpDoc

Best practice is close to the PhpDoc style. If you don't use an IDE like "Eclipse", you can just take a look at the PhpDoc Manual.

You don't have to know exactly how this works. Professional Developers can read the code anyway and just need this as a summary. Hobby coders and users might appreciate the way you explain it on the same knowledge level.

17

Use the Settings API before add_option

Instead of adding options to the DB via the add_option function, you should store them as an array with using the Settings API that takes care of everything for you.

Use the Theme Modifications API before add_option

The Modifications API is a pretty simple construct and a safe way that allows adding and retrieving options. Everything gets saved as serialized value in your database. Easy, safe & simple.

3
  • 1
    And furthermore, use update_option and never add_option, the update function will create the option when it does not exist.. :)
    – t31os
    Commented Feb 17, 2011 at 18:32
  • 3
    I wouldn't say never use add_option. There is a good use case for add_option where if the option is already set, it isn't changed, so I use it in activation to preserve possibly already existing user preferences.
    – ProfK
    Commented Oct 28, 2011 at 5:47
  • 1
    Another use case for add_option is when you want to explicitly disable auto loading. update_option will force autoload to true, so you want to disable autoload, use add_option when initially creating the option. Commented Jul 26, 2012 at 5:24
16

Protect Plugin Users Privacy

(Previously: Anonymous API Communication)

If a plug-in communicates with an external system or API (e.g. some Webservice), it should do so anonymously or provide the user with an anonymous option that ensures that no data related to the user of the plugin leaks to a second party uncontrolled.

0
15

Host Plugins on WordPress.org

Use the SVN repository provided on WordPress.org for hosting plugins. It makes for an easier update user-experience and if you've never used SVN before, it gets you to actually understand by using it in a context that justifies it.

15

Provide Access Control by Using Permissions

In many instances, users may not want everyone to have access to areas created by your plugin especially with plugins that do multiple complex operations, a single hardcoded capability check may not be enough.

At the very least, have appropriate capability checks for all of the different kind of procedures your plugin can be used for.

12

Import / Export Plugin Settings

It's not that common across plugins, but if your plugin has (some) settings, it should provide Import / Export of data like configuration and user input.

Import/Export improves the usability of a plugin.

An example-plugin that has such an import and export functionality (and as well an undo mechanism) is Breadcrumb NavXT (Wordpress Plugin) (full disclosure: some little code by me in there, most has been done by mtekk).

Related

12

Organize your code

It's alway hard to read code that's not written in the order it get's executed. First include/require, define, wp_enqueue_style & _script, etc., then the functions that the plugin/theme needs and at last the builder (ex. admin screen, stuff that integrates in the theme, etc.).

Try to separate things like css and js in their own folders. Also try to do this with functions that are only helpers, like array flatteners and similar. Keeping the "main" file as clean and easy to read as possible is a way that helps users, developers and you, when you try to update in a year and haven't seen the code for a longer time.

It's also good to have a structure you repeat often, so you always find your way through. Developing in a known structure on different projects will give you time to make it better and even if your client switches to another developer, you will never hear "he left a chaos". This builds your reputation and should be a long term goal.

1
  • I fear this is a bit too much about style that people would debate and not objective best practices with which all respected people would agree. It's very important we only address objective best practices so that people will be willing to agree to "bless" the list as opposed to having controversial items, no matter how well meant. Commented Aug 26, 2010 at 6:55
11

Die with style

die in a decent manner All of a plugins (and even themes) functions should use wp_die() in critical places to offer the user a little information on what had happened. Php errors are annoying and wp_die can give the user a nice styled message on what the plugin (or they) did wrong. Plus, if the user has debugging deactivated the plugin will just break.

Using wp_die() also helps that your plugins / themes are compatible with the wordpress testsuite.

Related:
11

Provide Help Screens for users

It is nicer to say RTFM (click help) as an answer than having to answer the question time and time again.

/**
  * Add contextual help for this screen
  * 
  * @param $rtfm
  * @uses get_current_screen
  */ 
  function ContextualHelp( /*string*/ $rtfm) 
  { 
     $current_screen = get_current_screen();
     if ($current_screen->id == $this->_pageid) 
     {
        $rtfm .= '<h3>The WordPress Plugin - Screen A</h3>';
        $rtfm .= '<p>Here are some tips: donate to me ' .
     }
     return $rtfm; 
  }
add_action('contextual_help', array($this,'ContextualHelp'),1,1);

update / note: (see comments from kaiser): the above example is to be used in a class

2
  • Should be in everyones toolbox (as long as you have to explain a specifc admin ui screen). +1
    – kaiser
    Commented Feb 18, 2011 at 14:58
  • Btw: You should mention, that this is meant to reside in a Class and how to interact with $this->_page_id & how it would be if you'd add the action hook from a functions.php or a plugin file without a Class.
    – kaiser
    Commented Feb 18, 2011 at 16:07
10

Offer Extensible Forms

When a plugin offers the possiblity to input data, it should always have a hook at the end, right before the "submit" and/or "reset" button, so developers can easily extend the form with not only fields, but buttons too.

See: Settings API

Related

9

include function always via Hook, not directly.

Example:

  • Dont use for include the class of the plugin via new without hook

  • Use the Hook plugins_loaded

    // add the class to WP                                   
    function my_plugin_start() {                                                               
        new my_plugin();   
    }                                                        
    add_action( 'plugins_loaded', 'my_plugin_start' );
    

Update: a small live example: Plugin-svn-trunk-page and a pseudo example

//avoid direct calls to this file where wp core files not present
if (!function_exists ('add_action')) {
        header('Status: 403 Forbidden');
        header('HTTP/1.1 403 Forbidden');
        exit();
}

if ( !class_exists( 'plugin_class' ) ) {
    class plugin_class {

        function __construct() {
        }

    } // end class

    function plugin_start() {

        new plugin_class();
    }

    add_action( 'plugins_loaded', 'plugin_start' );
} // end class_exists

You can also load via mu_plugins_loaded on multisite-install, see the codex for action reference: http://codex.wordpress.org/Plugin_API/Action_Reference Also here do you see, how inlcude wP with this hook: http://adambrown.info/p/wp_hooks/hook/plugins_loaded?version=2.1&file=wp-settings.php I uses this very often and its not so hard and early, better as an hard new class();

3
  • @bueltige --- could you explain this one a bit more Commented Feb 13, 2011 at 1:06
  • 3
    a small live example: [Plugin-svn-trunk-page]svn.wp-plugins.org/filter-rewrite-rules/trunk/… and a pseudo example //avoid direct calls to this file where wp core files not present if (!function_exists ('add_action')) { header('Status: 403 Forbidden'); header('HTTP/1.1 403 Forbidden'); exit(); } if ( !class_exists( 'plugin_class' ) ) { class plugin_class { function __construct() { } } // end class function plugin_start() { new plugin_class(); } add_action( 'plugins_loaded', 'plugin_start' ); } // end class_exists
    – bueltge
    Commented Feb 14, 2011 at 21:11
  • 2
    @Netconstructor.co - i have update the thread, the comment ist ugly for code
    – bueltge
    Commented Feb 14, 2011 at 21:14
8

License Plugins under a GPL Compatible License

Plug-ins and themes should be licensed under a WordPress-compatible license. This enables them to be re-distributed with WordPress as a "program." A recommended license is the GPL. Take care that all code libraries included with the plug-in are compatible with the same license.

(This has been a problem and serious point of debate both in the past and present.)

1
8

Your plugin description should accurately detail the functions of your plugin. There are 10 featured post plugins. All of them display featured posts, yet many have different features. It should be easy to compare your plugin to similar plugins by reading the description.

You should avoid bragging about how simple your plugin is unless it really is very basic. You should include useful links in the description like the link to the settings.

7

Minimize Side-effects of Remote Datasources and Webservices

A Plugin should Cache/Shield Webservice and/or XMLRPC/SOAP requests through a caching/data-provider layer if you use them so to not making front-requests waiting for (slow) webservice response.

That includes the download of RSS feed and other pages. Design your plugins that they request data in background.

One possible STEP is (Take posting to ping.fm as an example): Create a buffer table, let's say: ping_fm_buffer_post( date, time, message, submitted_time, status )

  1. For every time you want to submit update to ping.fm, add it to this table.
  2. Now, we need to create a plugin to handle this data. This plugin will run via crontab to check for every update that's not submitted yet
  3. Because we have this table, we can also list every message submitted to ping.fm and check each post's status. Just in case there's problem on ping.fm's side, we can re-submit it.
3
  • I don't really understand where you are exactly headed with this. Can you provide some links to supporting material? Commented Aug 25, 2010 at 19:39
  • Also, I'm not exactly sure what "Net Overhead" is. Isn't there a better term? If it's more clear it will be a better objective rule. And Prevent" is impossible; "Minimize" instead? Commented Aug 25, 2010 at 20:03
  • You're (probably) right. Bad wording and prevent is never possible, minimize better fits.
    – hakre
    Commented Aug 25, 2010 at 20:05
7

Test your plugin

We should definitively have some testing tools on our plugin development environment.

Based on this answer by Ethan Seifert to a testing question, these are good practices to follow:

  • Your Unit Testing should test the smallest amount of behavior that a class can perform.
  • When you get up to the level of functional testing this is where you can test you code with Wordpress dependencies.
  • Depending on what your plugin does -- consider using Selenium-based tests which test for the presence of data in the DOM by using IDs
3
  • While testing is important, saying unit tests should test the smallest instead of the greatest seems unwise. If you're having difficulty testing the WordPress dependent issues then just dive into the WordPress core, you'll find a whole bunch of internal global variables which you can use to see if items have worked.
    – Backie
    Commented Feb 16, 2011 at 10:51
  • 1
    But covering the smallest first is basic, so that you can reach the functional testing with WordPress as the answer says, isn't that right? Commented Feb 17, 2011 at 3:55
  • 1
    This is a plugin not an application, can you test a Java application without Java Runtime? Yes, by writing Java as a mockup and then test your plugin. Chances are the bugs are in your mockup. *) disclaimer or compiling it to native code.
    – edelwater
    Commented Feb 18, 2011 at 1:18

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