So, you’re looking to build a WordPress Plugin eh? Well here’s a couple things that I found after I started building my first plugins that I really wish I would’ve known beforehand. Now I’ve got a few hours ahead of me re-coding my plugins to my new standards (the things you’ll find below) which wouldn’t have taken near as much time if I would’ve done it right the first time…

So! Here’s a couple tips, along with some links to some excellent articles I’ve found that helped me along the way.

The Basics: Code and Organization

Probably one of the most important things in writing any code is structure and the way that you write. Consistency is always key. If your a seasoned developer this goes without saying, it becomes second nature to create good, nice and functional code – but I have the beginner in mind here. So if you’re just getting started, here’s a couple things to keep in mind when writing pretty much any piece of code.

Code Structure

Pick a function and variable naming convention and stick to it. Don’t have your first function called func_one() and the second one called secondFunction(). It makes it much easier to figure out your own code, because theres nothing worse than having to dig through your code triyng to figure out whether its func_one(), funcone() or funcOne(). (This also makes debugging alot easier.)

Also, WordPress officially dislikes camelCase names. Not that I really care, because if I like the way camelCase looks like or that’s what I’m used to I’m going to use it anyways. However keep in mind that if ever somebody else goes to work on your code and they are really into WordPress, then this is what they will expect as this is how the WordPress Core is built. Also, if you are relatively new to WordPress development you may find that you come to appreciate how it is that WordPress is written, and want your own functions to look WordPress-y. Food for thought anyways.

Another thing to remember is that on a standard WordPress installation, a user may have a large number of plugins installed, and because your plugins functions are globally available (ie: any code thats running on the server can call it) it means you may run into some name conflicts, such as if two plugins each had a function called “print_text()“. In order to avoid this, the best practice would be to put the majority of your plugins code inside a class with a unique name, like in the example below.

[codesyntax lang=”php” lines=”no”]

<?php

class my_plugin {

    /**
    * This is your plugins code
    */
    function do_something() {
       //Do something cool...
    }

}

?>

[/codesyntax]

Now, your functions themselves can have any name you want just as long as they’re in the uniquely named my_plugin class. To call one of these functions all you would have to do is create an instance of your class, and call the function like this:
[codesyntax lang=”php” lines=”no”]

<?php

   $my_plugin = new my_plugin();
   $my_plugin->do_something();

?>

[/codesyntax]
If you want more info on the ‘WordPress’ way of coding, then check out this WordPress Codex article.

Code Comments

What code comments do in a common IDE

Code comments in NetBeans

Code commenting is extremely easy to do as you go along, I mean, if you have a function, write out what it does. If this function takes arguments, write out what the arguments are and do. This makes it easier for you to pick up your code at a later time, or if in the future somebody else comes along and wants/needs to work on your code.

Also, the larger your plugin becomes, the easier it is to forget exactly how a function works. Plus, most development programs (such as NetBeans) are designed to work with comments in such a way is to make your development MUCH easier. (Like in the picture to the right)

In order to properly comment a function (in NetBeans at least) insert a /** ... /* just in front of your function declaration, like so:
[codesyntax lang=”php” lines=”no”]

<?php

/**
* This function does something pretty cool!!
*/
function test_function() {
   //Do something cool...
}

?>

[/codesyntax]
In addition, if your function takes arguments, you can put comments in for those as well so that you know what each argument is for.

[codesyntax lang=”php” lines=”no”]<?php

/**
* This function does something pretty cool!!
*
* @param int $cool1 This is the first cool argument passed to this test function! Its an integer...
* @param string|array $cool2 This is the second cool argument. This one can be either a string or an array...
*/
function test_function( $cool1, $cool2 ) {
   //Do something cool...
}

?>

[/codesyntax]

These are only a couple of the things that code comments can do for you. To find out more about how they can make your life ALOT easier, check out the information your development program provides.

It’s also worth noting that code commenting doesn’t end here. Always include inline comments inside of functions, especially in the case of a large block of code that could be confusing to read on its own. A quick one-line explanation of what the following code is about to accomplish can be a lifesaver.

Folder and File Organization

My plugin folder structure in an IDE

My plugin folder structure

When creating your plugin, remember to start organizing it right away. Start out by creating a folder for your plugin, calling the folder something unique so that another plugin won’t have the same name, such as ‘your_name-plugin_name’. So for me, my folder would be called ‘michael_blouin-cool_plugin.’ Next, you need to create a .php file in this folder with the exact same name as the folder itself. In addition to this PHP file, I like to include a few directories as well:

  • pages
  • css
  • js

This way, the different types of code are separated making it very easy to figure out where things are. Also, when I have code that outputs things like an HTML administration page, I put that in the ‘pages’ folder instead of in my main PHP file, which makes it alot easier to read.

Storing Information

WordPress has very handy means of storing information, so before you go ahead deciding how it is you’ll save information, check these out:

Saving Settings

If you’re looking to save small amounts of information (such as plugin settings & options) then WordPress provides a couple of means to do this.

The more hands on way is to manually store settings (normally as an array) using the options API. To do this, you make a call to get_option() and update_option(). This allows you complete control over how your admin pages display data to your users, and whats done with that data.

The following example demonstrates how to save and then retrieve plugin settings using get_option() and update_option().

[codesyntax lang=”php”]

<?php

/**
 * Saves the plugin settings using the WordPress Options API
 *
 * This function would likely be used on an admin page after checking to see if the user submitted
 * the form. One variable that it saves is a string, the other a number.
 */
function save_settings() {
    // Get the information that needs saving. (This assumes the information was submitted on a form).
    $admin_email = $_POST[ 'var1' ];
    $number = (int) $_POST[ 'var2' ];

    // Make an array out of what we want to save.
    $options = array(
        'admin_email' => $admin_email,
        'number' => $number
    );

    // Use WordPress to save this data.
    update_option( 'my_plugin-options', $var_array );
}

/**
 * Gets the saved settings for the plugin, echos them out, and then returns the array of settings.
 *
 * You would not normally echo out this information within the function that retrieves the settings,
 * I just included that to show how easy it is to access your settings after they're saved.
 *
 * @return type array
 */
function get_settings() {
    // Get the options that WordPress has stored.
    $options = get_option( 'my_plugin-options' );

    // Do something with the saved settings. In this case, echo them out.
    echo $options[ 'admin_email' ];
    echo $options[ 'number' ];

    // Return the options
    return $options;
}

?>

[/codesyntax]

Note: This code should definitely be placed within the plugin class!

The ‘Other’ Way (That just happens to be better)

The downside to doing it the first way is that you have to do everything manually. You need to manually create and check NONCES (more info) in order to secure your code, you need to print out the whole table of settings, descriptors etc and then you have to manually save and retrieve all this data from the settings API. What if you could do alot of that automatically?

Well you can.

Using the settings API, you can register fields using a simple callback mechanism and WordPress will take care of saving the data and securing the forms behind-the-scenes. You can still use custom validation or any custom means of having the user select your settings, but with a few less worries.

I’m not going to cover how it is that this is done, as there is already a fantastic tutorial that shows completely how to use this. It’s very easy to follow and understand, and I highly doubt I could top it so check it out on Ottopress.

Saving Data

The WordPress Database

The layout of the WordPress database.

If your like me when I started out, and your plugin needs to store data, then the first thing you’re thinking is: database tables! So pull out mysqli() and lets go!

But Wait.

The WordPress database is a thing of beauty. It is simple, elegant, and extend-able. For many of my initial ideas I started right off by creating my database structure, however further investigation showed that this was almost always more work for me than it needed to be, and that if I were to make it work within the already defined structure of WordPress, then my plugin could quickly inherit access to all the pre-existing and amazing WordPress functions. Furthermore, plugins created in such a manner are much more likely to play nicely with other plugins by other authors.

So how is it that you go about doing this? And where on earth do you store your data? Simple. The tables I’ve found to be the most useful are wp_posts and wp_post_meta. Take the example of an event calendar for starters. If you were planning this out, you may want to create tables in your database with the following layout (note that a very simple database layout is used here for illustrative purposes):

    table: calendar
       Columns: calendar_id, title, description, creator
    table: events
       Columns: event_id, calendar_id, title, description, start, end, creator

Now, all of the events in the events table would need to refer back to one of the calendars in the calendar table (this way you can have more than one calendar). In this case, the calendar basically becomes a means of organizing events; a taxonomy if you will. So why is it that you shouldn’t create a database table for this? Because if you examine the structure of the wp_posts table and the wp_posts_meta table, all of this functionality exists with custom post types. If you don’t know what these are, check out this awesome explanation by Justin Tadlock (who, by the way, deserves the credit for the inspiration of the topic of this example).

If you were to go ahead and create an ‘event’ custom post type, the problem of “calendars” would be solved by using regular WordPress categories as your organizational elements (ie: calendars). Now you simply need to create a plugin that tweaks the admin page using meta boxes (see here for the meta box tutorial). Yhe purpose of this example however, is not to explain how to create a calendar plugin using custom post types, its simply to illustrate how an idea can be changed to use the pre-existing WordPress infrastructure, and thus will end here. However, if you would like a calendar like this, or would like to take a look at a real life example, check out my MB Calendar Plugin.

Now, taking the existing WordPress infrastructure into account, it’s worth mentioning that there are valid reasons for creating your own database tables, however it depends on your project and I do strongly encourage you to consider whether or not your plugin actually requires them. If you decide that your plugin must in fact have its own tables in the database, then please, use the builtin WordPress function $wpdb->blog_prefix to prefix the tables in your database. Otherwise, if you’re plugin is installed in a Multisite configuration, or with the WP_Hive plugin it will not work correctly on each blog. (Unless of course your plugin is in fact intended to hold information consistantly between multiple blogs.)

The Two Golden Rules

If you don’t know, look. If you can’t find it, ask.

Nothings more maddening than when you can’t figure out some weird problem, or your not sure how to do something. Except maybe one thing: when the asker in a forum has obviously not done the first simple step to resolving any problem: Google it. If you’re in a bind, make sure you’ve looked into it a bit first before asking for help, and when you do, always remember to be polite as these friendly folks are helping you out on their own free time and no personal obligation. That said, here are a couple handy places I’ve found for getting help on WordPress related problems:

  • WordPress.org
  • StackOverflow.com

Keep it Simple

Above all things, the golden rule is always keeping it simple. Go for ease of use when coding, because YOU are the developer! There’s no need to impress yourself with how beautiful and confusing your code is, instead, make sure that in a year or two when you come back to this plugin you can figure it out without too much time spent jumping between functions and banging your head against the wall. Also, you may not think there’s a need for it, but often times people find they need to modify a plugin to do exactly what they want. If you keep the plugin code clean and easy to understand, you’ll be helping them out alot. Even if you aren’t planning on releasing right away, you never know what will happen!

 

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

By submitting a comment you are granting Michael Blouin a perpetual license to reproduce your words and name/web site in attribution. Inappropriate and irrelevant comments will be removed at my discretion.