Techblog Index

5 best practices on developing WordPress plugins

Wordpress Plugins
Wordpress wonders me how it born as a Blogging platform and is growing a powerful CMS platform. Its plugin framework is full of hooks and actions and almost everything can be trapped and modified by plugins.

As WordPress is a Procedural Programmingw oriented platform the function wrapped to the hooks and actions have no scope when called except global this can be hell when developing plugins. We must take extra-care to not compromise our plugin security and compatibility.

In our road developing plugins we learned some lessons, here is our share.

1. Enable your WP_DEBUG

This caused me some nightmares the first time I turned it on. Lots of plugin developers doesn’t have the habit of working with PHP’s error_reporting at the E_ALL level (Maximum Level, including notices of undefined variables) and I god SEVERAL notices on screen.

WP_DEBUG can be enabled by simply adding the following line to your wp-config.php file.

define('WP_DEBUG',true);

PHP is a very friendly (if we can call this way) programming language that doesn’t cares very much to variable initialization but you should initialize all your variables and check if they are set with the language’s native isset() function.

If you have WP_DEBUG you will se NO errors at all so if your script breaks somewhere at the development, you’ll suffer lots of pain trying to blindly debug your code. Lots of experience had me finding unclosed brackets, parentheses and semicolons but, come on, I’m no masochist.

The best tip here is to have a development WordPress installation. If this is not possible (or you are just too lazy), as lots of plugin developers (very popular ones) aren’t caring about notices showing up to your visitors if you have WP_DEBUG enabled you can always use the good and old PHP code to enable debug only if you are the visitor.

# 200.200.200.200 is an example IP and should be replaced by your own
# if you don't know your IP you can visit www.whatismyip.com
if ($_SERVER['REMOTE_ADDR'] == '200.200.200.200') define('WP_DEBUG',true);

2. Have a cleanup deactivation routine

Had you ever took a look at your wp_options table after a long time activating and deactivating plugins? If you so you probably had seen the garbage left out there.

If you are going to write an option with add_option or update_option please, please, please, be sure to remove your options upon plugin deactivation. I'm pretty sure no one wants your options leftovers as a souvenir.

To achieve such thing, you must register a deactivation hook by the register_deactivation_hook as following

register_deactivation_hook( __FILE__, 'plugin_deactivate' );

And obviously you will have to code an appropriate deactivation function, like plugin_deactivate in the example.

NOTE: Your deactivation function must be at the script's main PHP file.
NOTE: Your deactivation function may have any name.
NOTE: The __FILE__ part specified at the deactivation hook is referencing your own script file.

I personally put all my options that goes to the wp_options database in a global associative array so if I add more options my cleanup function will still be compliant.

global $aOptions;
$aOptions = array(
    'myplugin-default-lang' => 'en_US'
);

I also put my deactivation and cleanup functions apart so I can call the cleanup from within the deactivation function. This is made so if I want to add more deactivation functionalities else than cleanup I can do this without polluting my cleanup function with non-cleanup procedures.

The plugin_deactivate function will look like the following:

function plugin_deactivate() {
    // Cleanup
    plugin_cleanup();
} // end :: function :: plugin_deactivate

And the cleanup function as it follows:

function plugin_cleanup() {
 
    global $aOptions;
 
    // Delete our options
    foreach ($aOptions as $sOptionKey => $sOptionValue):
        delete_option($sOptionKey);
    endforeach;
 
} // end :: function :: plugin_cleanup

This should be enough to keep your options table tidy.

3. Protect files that shouldn't be accessed directly

Almost all your plugin files shouldn't be access directly. Exception goes to scripts that receives data from outside the WordPress framework like thumbnail generators, image replacement techniques, AJAX, and such.

To disable direct access to your PHP files you must check if some WordPress function is present and if not, shutdown the script if a good and old exit(); call.

The example goes as:

if (!function_exists ('add_action')): 
    header('Status: 403 Forbidden');
    header('HTTP/1.1 403 Forbidden');
    exit();
endif;

The example above also sends a 403 header in both formats (Internet Explorer and decent browsers, respectively).

4. Use internationalization even if you aren't going to translate yet

Even if you are not planning release you plugin with many languages I strongly recommend that you build yours i18n-ready by wrapping your texts on gettextw functions so other users can help (or even you in the future) to translate your plugin.

The basics

Internationalization basics in PHP is very simple. There are mainly two functions: __() and _e(). The difference is that __() returns the internationalized string _e() echoes it.

When text is within a variable or returned by a function you should use the __() function and if you want to echo it, _e() instead.

Echoing internationalized text in a template file

<h2><?php _e('My text goes here','My text domain goes here'); ?></h2>

Returning internationalized text in a function

function somefunction() {
    return __('My text goes here','My text domain goes here');</h2>
} // end :: function :: somefunction

Internationalization is a wide subject and is covered greatly in the WordPress "Writing a Plugin" page.

Internationalizing your plugin is also a good marketing strategy since if someone releases a language file for your plugin, is also making it available in a wider market-share slice.

5. Employ current coding best practices

There are some wide best practices that are not exclusively to the WordPress Plugin scope.

Separate your code

Applying this technique on WordPress Plugin development is such as having the plugin's main php file just making the calls and registering the hooks and have your functions properly laid under a lib/ function or such. Same things goes to images/, js/ (JavaScript) and css/.

Document your code

Ok, this is like telling grown-ups to not touch the hot oven or putting the finger in a wall socket but many people still lacks in documenting code.

I suggest to keep your functions, classes and files documented in the phpDocumentor syntax.

This kind of syntax is inherited from Java and other languages apply it since is very readable and parse-able.

It goes like the following:

/**
 * My loved function
 *
 * This function collects some data and process in this way to give the desired result.
 *
 * @param    string   $varname    Description of the variable
 * @param    int   $othervarname    Description of the variable
 * @return    void   This function returns nothing
 */

Stay DRY

Try to avoid two functions that do basically the same thing. If you have two functions in separate classes that to the same thing (like string sanitization), consider having a utility class.

Bonus Tip!

Avoid kidnapping people's wp_head() and wp_footer() with your plugin propaganda. If you want to make such thing, do as HTML code comment or make this branding stuff optional.

If you are going to make your plugin free, make it free, not AD dependant. If you think your plugin should be paid, then make it paid. Placing plugin ADs in the themplate may scare out some users. Your free plugin shall make your own propaganda by being useful and rich-featured, not by printing it out.

What's your tip?

 
 

Leave a Reply