Documentation

Code Comments Code Comments

Code should be commented thoroughly throughout to ensure that code remains readable, approachable, and understandable to anyone reading it.

When writing comments, it’s important to ensure that you’re documenting the intent and motivation of the code, rather than merely repeating the code. Well-written code should be inherently understandable, but does not convey why the code exists and is written that way.

For example, the following comments merely repeat the code, and are not useful:

// Avoid:

// Set the subtotal to 0
$subtotal = 0;

// Loop over each product
foreach ( $products as $product ) {
    // Add the price of the product to the subtotal
    $subtotal += $product->price;
}

// Multiple subtotal by 0.1 to get taxes
$taxes = $subtotal * 0.1;

// Add subtotal to taxes for total
$total = $subtotal + $taxes;

Instead, we should document the intent of the code where it makes sense, and let the code speak for itself in obvious places.

// Prefer:

// Generate subtotal from prices
$subtotal = 0;
foreach ( $products as $product ) {
    $subtotal += $product->price;
}

// Calculate tax based on 10% rate (GST)
$taxes = $subtotal * 0.1;
$total = $subtotal + $taxes;

This could be improved further by making the code clearer by removing “magic numbers” and turning them into constants instead.

/**
 * Effective tax rate (Australia)
 *
 * GST tax rate, applied to all non-exempt goods and services.
 */
const TAX_RATE = 0.1;

// [...]

$taxes = $subtotal * TAX_RATE;

Inline comments used correctly should add to the readability of the code by providing context on decisions.

Documentation Blocks Documentation Blocks

Documentation blocks (or “doc blocks”) are specific types of inline comments with semantic meaning. These are typically attached to a “structural element” (e.g. function, class, etc) and document the element’s behaviour and intent.

Doc blocks have a machine readable structure, allowing most editors and IDEs to pull out their data and display it in the editor. This allows better code completion tooling, and allows automated documentation to be generated for the project.

Our coding standards require the use of documentation blocks where possible.

In doc blocks, you should state the behaviour of the overall element, allowing the element to be understood without viewing the source. Again, this does not mean repeating the code, but rather stating why the element should be used.

For example:

// Avoid:
/**
 * Multiply tax rate by subtotal
 *
 * @param int $subtotal Subtotal
 * @return int Subtotal multiplied by tax rate
 */
function get_tax( $subtotal ) {
    return $subtotal * TAX_RATE;
}

// Prefer:
/**
 * Calculate tax rate for a given subtotal
 *
 * @param int $subtotal
 * @return int Effective tax amount
 */
function get_tax( $subtotal ) {
    return $subtotal * TAX_RATE;
}

Excessive Commenting Excessive Commenting

When commenting code, you need to exercise judgement on when to comment. Poorly written inline comments can reduce the readability of the code by breaking up the mental flow of reading code, and make the code less maintainable.

For example, the following code contains 9 lines of code, but the comments break it up in to an unreadable 40 lines:

/**
 * This issue only arrises when breadcrumbs are placed inside of The Loop,
 * so we'll first check to see if we're in The Loop, and if not, just bail
 * on this altogether.
 */
$in_the_loop = (bool) in_the_loop();
if ( ! $in_the_loop ) {
    return $breadcrumb_text;
}

/**
 * Grab the post subtitle.
 *
 * Example: (string) "Subtitle"
 */
$post_subtitle = get_the_subtitle();

/**
 * Grab the length of the post subtitle.
 *
 * We're also using a negative value of the legnth of the subtitle.
 *
 * Example: (int) 8
 */
$post_subtitle_length = (int) strlen( $post_subtitle );
$post_subtitle_length_neg = -1 * $post_subtitle_length;

/**
 * Grab the already filtered post title.
 *
 * Example: (string) "Post TitleSubtitle"
 */
$post_title = (string) $breadcrumb_text['text'];

/**
 * Grab the length of the filtered post title.
 *
 * Example: (int) 18
 */
$post_title_length = (int) strlen( $post_title );

(Example shortened from the original for brevity.)

Instead, this code should simply document the intent of the code where necessary, and let the code speak for itself:

// This issue only arises when breadcrumbs are placed inside of The Loop
$in_the_loop = (bool) in_the_loop();
if ( ! $in_the_loop ) {
    return $breadcrumb_text;
}

$post_title = (string) $breadcrumb_text['text'];
$post_subtitle = get_the_subtitle();

// Calculate lengths to avoid repeated calls
$post_subtitle_length = (int) strlen( $post_subtitle );
$post_subtitle_length_neg = -1 * $post_subtitle_length;
$post_title_length = (int) strlen( $post_title );

Note that this example is about the commenting style only. In practice, this code should be rewritten to avoid micro-optimisations and unnecessary code.

Prose Documentation Prose Documentation

Prose documentation is important for understanding the project at a higher level. This is where you can document decisions made about architecture, choice of external libraries and plugins, and process.

Generally speaking, long-lived documentation for a project should live on the project’s wiki in GitHub. This provides a version-controlled, Markdown-capable repository of information about the project, and is conveniently located alongside the code and issues.

Projects should also contain READMEs, but you should avoid overloading these with documentation. Instead, have the README lay out the basics of getting started with the project (i.e. instructions for installation), and link out to select pages on the wiki.