Drop Shadow

Programming style guide

When developing for the USD web server or web sites, we have a few style guidelines which must be followed. These styles will increase the readability of your code when other people at USD look at them. They will also increase the speed—and reliability—of changes made directly on the server under emergency or stressful conditions.

Some of these guidelines ensure that code is easily edited in more than one environment, from a large screen to a tiny terminal; some ensure that the code is specifically easily edited on the server; other guidelines set a standard format so that all programmers know what to expect when looking at each other’s code. In some cases, our requirements are no better and no worse than some of the alternatives, but we still require that you follow the guidelines because mixed styles will reduce readability and reliability.

Indentation

Use tabs, not spaces, for indentation. Always indent blocks of code one tab (and only one tab) beyond their parent structure. You can set your text editor to display tabs however you wish; your files must be written with tabs for indentation, however.

Never combine multiple statements on the same line.

Braces go on the same line as their control structure. A closing brace on its own should mean that this block has ended and there are no more conditions to test. For example:

if ($newsList !== false) { if (!$newsList && !$eventsList) { $replacees = array('title', 'items'); $replacers = array('News and Events', '<li class="nonews">No current news & events</li>'); $newsList = $this->mergeTemplate($replacees, $replacers, 'news/group'); } elseif ($newsList && $eventsList) { $newsList = $newsList . "\n" . $eventsList; } elseif ($eventsList) { $newsList = $eventsList; } else { $newsList = null; } }

Try not to put spaces between function names and the opening parentheses of the parameter list, and try to use spaces after commas in parameter lists. Try to use spaces around operators.

Line endings

Always ensure that when you transfer files to the server that they use Unix line endings (character 10, or hex 0A). The easiest way to do this is to set your text editor to use Unix line endings. Your text editor will be able to do this.

Multi-line arrays

It is usually a good idea to keep lines short, which means that sometimes you’ll want your arrays to span multiple lines. When you do this, put all of the data pieces on their own, indented, line. For example:

fileExtensions = ( ("php", "Dynamic PHP page"), ("html", "Static HTML page"), ("shtml", "Old dynamic HTML page"), ("pdf", "Adobe PDF document"), ("jpg", "JPEG image"), ("png", "Portable Network Graphics image"), ("rss", "RSS Feed"), ("css", "Cascading Style Sheet"), ("dtd", "RSS DTD"), ("xslt", "XML Stylesheet"), ("zip", "Compressed zip archive"), ("folder", "Folder"), ("gif", "Graphics Interchange Format"), )

If the scripting language allows it, put a comma (or appropriate item delimiter) on the last line. This makes it easier to add new items and adjust the position of existing items.

This follows generally to any single line that needs to be broken into multiple lines for readability. Do not try to mix structure with content. In other words, don’t try to match the indentation level to a specific number of characters.

One-line IFs

Do not combine control structures and their blocks on the same line, even when the block itself is only one line. Always put conditional statements on their own line.

The only exception is when (a) both the test condition and the resulting action are extremely short, and (b) the nature of the statement is such that we will never need to add more statements to the block. For example, this might be okay:

if ($options['no-red']) $ball = str_replace('red', 'grey'); if ($options['use-rubber']) $ball = str_replace('plastic', 'rubber');

In general, however, such structures will almost always be better handled through some function call that duplicates the functionality.

Never combine two different formats. For example, do not do this:

if ($options['no-red']) $ball = str_replace('red', 'grey'); elseif ($options['use-rubber']) { $ball = str_replace('plastic', 'rubber'); $ball = str_replace('vinyl', 'rubber'); }

As soon as the structure becomes complex, use one line for the test and one for the statement:

if ($options['no-red']) { $ball = str_replace('red', 'grey'); } elseif ($options['use-rubber']) { $ball = str_replace('plastic', 'rubber'); $ball = str_replace('vinyl', 'rubber'); }

The same restriction applies to anterior if structures in Perl (and any other language that supports anterior if). They may be appropriate for short test conditions and short statements, but otherwise use the multi-line format.

When in doubt, separate the test from the conditional code.

C vs. Pascal control structure syntax

In PHP, you have the option of using either braces or a Pascal-like syntax which uses the name for the end of the control structure and colons for the beginning. Except for code meant for non-programmers, which you use is up to you.

If you choose to use Pascal-like syntax, use all-capitals for the start and end of the control structures.

Here’s the indentation example using Pascal-like syntax:

IF ($newsList !== false): IF (!$newsList && !$eventsList): $replacees = array('title', 'items'); $replacers = array('News and Events', '<li class="nonews">No current news & events</li>'); $newsList = $this->mergeTemplate($replacees, $replacers, 'news/group'); ELSEIF ($newsList && $eventsList): $newsList = $newsList . "\n" . $eventsList; ELSEIF ($eventsList): $newsList = $eventsList; ELSE: $newsList = null; ENDIF; ENDIF;

If you have no preference, then use the Pascal-like syntax when mixing HTML and PHP to improve the readability of the HTML, but use the C-like syntax in long blocks of PHP code.

For example, this is usually more readable than the C-like counterpart:

<?IF ($insertID = $db->replace($updateFields, $extraFields)):?> --long section of HTML <?ELSE:?> --long section of HTML <?ENDIF;?>

You should never have a lone brace in its own section of PHP: “<? } ?>”. Generally, if the closing brace isn’t part of the same PHP block as the opening brace, you should use the Pascal-like syntax.

When writing code that might be edited by non-programmers, always use Pascal-like syntax. The PHP control structures that don’t support Pascal-like syntax are structures that shouldn’t be visible to non-programmers anyway (functions and classes, for example); in general, you will want to keep such definitions out of pages that will be edited by non-programmers. Place them in a separate file and either “include” or ”require” that file.

Variable, function, and class names

Your variable/property names and function/method names must be self-commenting, but otherwise you can use any style with which you are willing to be consistent when working on your own code.

Part of self-commenting variable names is consistency. For example, if you’re pulling the title, description, and URL of a news item, you might call them $news_title, $news_description, and $news_URL; or you might call them $title, $description, and $URL. But you should not call them $news_title, $description, and $itemURL. Variables must be consistently named.

Do not create obscure abbreviations. If referring to an IP address, $ip might be okay. But using $qr to refer to a query result is not okay.

If a built-in function has an alias, use the real function name, not the alias. In PHP, for example, always use “exit” rather than “die” and “implode” rather than “join”.

Use the same style throughout your code. You may find it useful to switch styles depending on who you are writing the code for, but once you have chosen a style for a project, use that style consistently throughout that project.

When working on someone else’s code, use their style.

The two most common forms for variable and function names used on USD’s web site are lowerCamelCase and underscore-style. Both improve readability by marking where words begin and end.

//lowerCamelCase $newsTitle = $this->shortenTitle();

//underscore style $news_title = $this->shorten_title();

If you do not have a preference, use lowerCamelCase.

Class names must use TitleCase.

Code comments

Every file must have a comment at the top describing the file’s purpose. Write them so that people can understand them on their own.

Use comments as necessary to illuminate obscure conditions.

Use comments to describe the intent of a function or block. Comments should explain why this code is here; the code itself should explain how it does what it does. Remember that even self-commenting code may fail to correctly comment if the code does not successfully implement your intent.

All changes must be pushed back to the Mercurial repository. Name the file changed, describe the change, and explain the behavior that required the change.

Bare constants

Every variable you use should have a known purpose. Bare constants don’t display their purpose, so don’t use them. For example, don’t do this:

$newsfeed->display(3, 6);

or even:

$newsfeed->display('faculty', 6);

Instead, do this:

//display six news items of interest to faculty $audience = 3; //or $audience = 'faculty' $maxItems = 6; $newsfeed->display($audience, $maxItems);

This helps ensure that someone else coming to the code understands what those numbers mean.

Undocumented features

There are no undocumented features, there are only bugs waiting to happen. Do not use obscure functionality that is not documented and/or that just happens to work because of a quirk of the language’s current implementation.

Never take advantage of bugs or limitations in a language’s current implementation.

It follows that you cannot simply keep trying different permutations until something “works”. You may have blundered into something that works now but that won’t work with the next revision of the language, or that works on your browser but that doesn’t work on other browsers. Start from a description of the standard or the documentation for the language.

Which language should you use?

Use the most appropriate language for the task. However, the language must be open source, preferably pre-installed on most Unix servers (for server-side code), and perceivable on all browsers, even non-visual ones (for client-side code).

At USD, we usually use PHP for programming inside of web pages, Perl for creating cron jobs or other command-line scripts (especially text filters), and Python for creating more complex web applications.