planetOzh, Make Clean and Readable Sources — Why and How,

In August 2008 I made a quick review of 50 plugins (part 1, part 2) and was really surprised by the number of coders who ship plugins with barely readable code. Working, even clever, but ugly code.

Making clean sources is not a useless mania of a compulsive obsessive geek, it's truly a requisite for maintainable code. It won't make your code good — just better.

For less experienced coders here are a few rules of thumb I try to follow. That's just my word and my coding habits, nothing is to be considered as the definitive best practice, but I hope this will make anyway a good pointer for novices.

Good Plugin Habits: Make clean and readable sources

As a WordPress plugins coder, mostly everything I know, I've learnt it by reading sources: find about a plugin that does something, wonder how I would do that or even how such a thing is possible, then read the plugin source to compare their solution and mine, or even just learn about a new trick, a new API or a function I didn't know about. I barely read instructions or readmes, but I always read the sources.

And as a WordPress plugins releaser, I maintain a number of scripts. I wrote some of them four years ago, and anyway most of the time when I haven't worked on a plugin for more than a couple of months, I totally forget how I coded it. Maintaining plugins means updating them once in a while: either someone finds a bug, or the WordPress code and APIs evolve in a way that breaks the plugin, so I have to rewrite parts of it. Basically, this means rediscovering my own plugin: read the sources, wonder how I did this and why I did that. Needless to say, this is much less cumbersome if the source is clean.

To me, making clean sources is twofold: help others reading my code, but primarily help the future-me maintaining outdated stuff. If someone finds your source hardly readable, you will too.

This said, how do you keep your plugin sources tidy and clean? Nothing rocket science and just common sense, really:

Make blocks visually identifiable, put a few blank lines between distinct actions, function declarations. Space is cheap, put some where it makes sense.

Be descriptive

For most of the code, things are self explanatory if well named. Reading a block of PHP code should be almost like reading basic English. A loop increment can be named $i, but give all your function and variables a name that will unmistakably tell the reader what they do or what they are for.

Give functions, important variables and constants a self explanatory name.

Comment the source

Don't state the obvious : don't comment trivial things (everybody will understand what function myplugin_create_default_database() is for) but you have to add some insight to its tricky parts. Comments are not there to turn your work into a coding tutorial where you explain the basis, you write comments primarily for you.

When reading a code block, one should understand all of the 3 following key points:

What: the aim

How: the method

Why: the reason

The What and the How may not require even require comments. Sometimes, giving the function a self explanatory name will be enough.

The How could either be a detailed comment at the beginning of the block, or several one liners inside it, before each key part (that should be visually separated by a blank line)

The Why is really the crucial part. Whenever you're making a design choice, this has to be explained and justified, for two reasons. First, you'll want to understand a tricky bit of code in 2 years when you read it again. And second, you'll want to be able to understand the reasoning behind this decision, and eventually be able to make another, and hopefully better, design choice. Whenever you spent some time in your code on a problem, spend an extra minute explaining how you handled it.

Comments are primarily for the future you.

If not obvious by the code, comments should say What and How. If it required some thoughts, comments must say Why.

A comment can be really anything you feel comfortable with: brief explanations, more detailed stuff, formal or informal, as long as it doesn't make your code slower to read (explain, don't distract). Still, there is a rather widely adopted convention over a few keywords in comments, and amongst them: TODO: and FIXME:

TODO: indicates that a part can be extended, adding features for instance. Additional code should go here at some point of the development.

FIXME: shows parts that must be improved: fix a bug or potential bug, rewrite a time consuming loop…

Leave these comments as notes for the future you or for someone else.

Another set of strange keywords you'll find, in most of WordPress' core files now, are what is called Javadoc. These look like the following:

* @return null Will return null if $tag does not exist in $wp_filter array

*/

function do_action($tag, $arg = '') {

...

This standard way of commenting allow some tools to generate automated documentation (see image here) and also enforces attention to details and strictness when coding: did I provide a function description? Am I sure it will only accept strings? Will this always return a boolean?

This comment syntax is really valuable on larger team projects, but I find it a bit overkill for my personal plugin coding needs.

Split in several files

Make several smaller files instead of one big file, group functions in different files by topic, as this will have several virtues

First, it makes things prettier, which will make you prouder. As simple as this :) One short main plugin file, and various directories for images, CSS, javascripts, PHP includes, translation files,…

Second, when a particular WordPress API evolves and breaks your plugin (and this will happen), you'll know which small file needs work: the one with comments function, the one dealing with the admin interface? It's much less burdensome to rework a tiny homogenous file than a big one.

Third, split for performance. Making various small files will allow you conditionally include them only if they are needed. For instance, group all the admin interface functions in plugindir/includes/admin.php and in your main plugin file where the plugin initializes everything use something like:

Start splitting and organizing your files from the start, not when you have 15 different files in the same directory.

Stick to one syntax

Once you are comfortable with a coding style, stick to it. If you prefer to indent with 4 spaces instead of 1 tab, naming with CamelCase (joeCreateDatabase() or underscore separation (joe_create_database()), putting curly brackets before of after a line break… it's all up to you, as long as you're consistent across your files.

As reference, the adopted coding style for WordPress core files seems to be:

Real tabs in front, and spaces to align elements where that improves readability

Braces used for multiline blocks but avoided when possible (single line)

Variables on the right side of logical comparisons

Use the same coding style as in the WordPress core files, if possible.

Group hooks

My personal preference is to group hooks (add_action()and add_filter()) all together at the end of the main plugin file, rather than spread all over the file. I've found that it makes things a lot easier when you try to figure out what's going on, and what is the typical "flow" of events, especially when they refer to aptly named functions.

Grouping hooks makes like a summary of your plugin: what it does, and when.

Thanks for your articles, this will be my second year working on WordPress Platforms, and thought I'd do some refreshers to start the year on the right foot. Love your tips, easy to read, and understand. Great resource.

"Avoid unnecessary levels of indentation by dealing with potential failure scenarios first and then moving on to the success scenario."

I see too many developers writing code whereby they only check for success scenarios, leaving failure scenarios to 'else' blocks further down the code, which are increasingly difficult to match to the original condition, especially where indentation isn't consistent (i.e. mixes tabs and spaces!).

The idea is not to put huge chunks of code in ever-increasing levels of indentation. Use 'continue' to move on to the next iteration of a loop if conditions haven't been met. Use 'return' early on in functions if conditions haven't been met.

I love WordPress plugins so I wrote a book!

This site

This is planetOzh, weblog of Ozh, a 35 years old dude living in France with an interest for, errr, like, computer things. I have a wife, 2 kids, and one computer-unrelated job. Give my eye a gentle click to read more about me.

This page

This page was written on 2008 / August / 15 (6 years 11 months 3 weeks and 2 days ago)