Difference between revisions of "Coding standards"

From WormBaseWiki
Jump to navigationJump to search
 
(9 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= File and Directory Names =
 
 
= Code Formatting =
 
 
== Indentation ==
 
 
 
= WormBase Coding Standards and Style Guide =
 
= WormBase Coding Standards and Style Guide =
 
  
 
== Quick Reference ==
 
== Quick Reference ==
 
Formatting conventions
 
  
 
{|table border=1
 
{|table border=1
Line 36: Line 27:
 
|}
 
|}
  
 +
=Specific Guidelines=
  
Naming Conventions
+
==Executables==
Names representing modules SHOULD be in all lower case.
 
  
Names representing types (classes) MUST be nouns and written using CamelCase capitalization:
+
Scripts must be named according to the function they carry out.
  
Account, EventHandler
+
<pre>
Constants SHOULD be placed within a single object created as a holder for constants, emulating an Enum; the enum SHOULD be named appropriately, and members SHOULD be named using either CamelCase or UPPER_CASE capitalization:
+
# YES!
 +
build_intermine.sh
  
var NodeTypes = {
+
# NO!
    Element : 1,
+
x
    DOCUMENT: 2
+
</pre>
}
+
 
Abbreviations and acronyms SHOULD NOT be UPPERCASE when used as a name:
+
Scripts must have a suffix that denotes their type (BASH scripts: .sh, Perl scripts: .pl, Ruby scripts: .rb).
 +
 
 +
<pre>
 +
# YES!
 +
get_gene_ontology.pl
 +
 
 +
# NO!
 +
build_db
 +
</pre>
 +
 
 +
==Variables==
 +
 
 +
Variable names should reflect the content of the variable.  Be appropriately verbose so that the variable contents are clear.
  
getInnerHtml(), getXml(), XmlDocument
+
Abbreviations and acronyms should be UPPERCASE when used as a name:
Names representing methods SHOULD be verbs or verb phrases:
 
  
obj.getSomeValue()
+
<pre>
Public class variables MUST be written using mixedCase capitalization.
+
print_HTML();
 +
</pre>
  
 
CSS variable names SHOULD follow the same conventions as public class variables.
 
CSS variable names SHOULD follow the same conventions as public class variables.
  
Private class variables MAY be written using _mixedCase (with preceding underscore):
+
Private class variables should be written using lowercase with a preceding underscore):
  
var MyClass = function(){
+
<pre>
    var _buffer;
+
sub _my_private_function {
    this.doSomething = function(){
+
  my ($self,@args) = @_;
    };
+
  ...
 
}
 
}
Variables that are intended to be private, but are not closure bound, SHOULD be prepended with a "_" (underscore) char:
+
</pre>
  
this._somePrivateVariable = statement;
+
Variables with a large scope SHOULD have globally unambiguous names; ambiguity MAY be distinguished by module membership. Variables with small or private scope MAY have terse names.
Note: the above variable also follows the convention for a private variable.
 
  
Generic variables SHOULD have the same name as their type:
+
Public names SHOULD be as clear as necessary and SHOULD avoid unclear shortenings and contractions:
  
setTopic(topic) // where topic is of type Topic
+
<pre>get_BLAST_hits</pre> NOT <pre>gbh();</pre>
All names SHOULD be written in English.
 
  
Variables with a large scope SHOULD have globally unambiguous names; ambiguity MAY be distinguished by module membership. Variables with small or private scope MAY have terse names.
+
Iterator variables SHOULD be called "i", "j", "k", etc.
  
The name of the return object is implicit, and SHOULD be avoided in a method name:
+
Abbreviations in names SHOULD be avoided.
  
getHandler(); // NOT getEventHandler()
+
Variables SHOULD be initialized where they are declared and they SHOULD be declared in the smallest scope possible. A null initialization is acceptable.
Public names SHOULD be as clear as necessary and SHOULD avoid unclear shortenings and contractions:
 
  
MouseEventHandler, NOT MseEvtHdlr.
+
Variables MUST never have a dual meaning.
Note that, again, any context that can be determined by module membership SHOULD be used when determining if a variable name is clear. For example, a class that represents a mouse event handler:
 
  
dojo.events.mouse.Handler // NOT dojo.events.mouse.MouseEventHandler
+
Related variables of the same type CAN be declared in a common statement; unrelated variables SHOULD NOT be declared in the same statement.
Classes/constructors MAY be named based on their inheritance pattern, with the base class to the right of the name:
 
  
EventHandler
+
Variables SHOULD be kept alive for as short a time as possible.
UIEventHandler
 
MouseEventHandler
 
The base class CAN be dropped from a name if it is obviously implicit in the name:
 
  
MouseEventHandler as opposed to MouseUIEventHandler.
+
Hash keys are unquoted unless absolutely necessary. If quotes are necessary, you should change your hash key.
Specific Naming Conventions
 
The terms get/set SHOULD NOT used where a field is accessed, unless the variable being accessed is lexically private.
 
  
The "is" prefix SHOULD be used for boolean variables and methods. Alternatives include "has", "can" and "should"
+
<pre>
 +
# YES!
 +
$hash{carrot} = 'orange';
  
The term "compute" CAN be used in methods where something is computed.
+
# NO!
 +
$hash{'carrot'} = 'orange';
 +
</pre>
  
The term "find" CAN be used in methods where something is looked up.
+
==Files==
  
The terms "initialize" or "init" CAN be used where an object or a concept is established.
+
Class or object-per-file guidelines are not yet determined.
  
UI Control variables SHOULD be suffixed by the control type. Examples: leftComboBox, topScrollPane
+
Tabs (set to 4 spaces) SHOULD be used for indentation.
  
Plural form MUST be used to name collections.
 
  
A "num" prefix or "count" postfix SHOULD be used for variables representing a number of objects.
+
==Loops / iterative declarations==
  
Iterator variables SHOULD be called "i", "j", "k", etc.
+
Only loop control statements MUST be included in the "for" loop construction.
  
Complement names MUST be used for complement entities. Examples: get/set, add/remove, create/destroy, start/stop, insert/delete, begin/end, etc.
+
==Conditionals==
  
Abbreviations in names SHOULD be avoided.
+
Complex conditional expressions SHOULD be avoided; use temporary boolean variables instead.
  
Negated boolean variable names MUST be avoided:
+
The nominal case SHOULD be put in the "if" part and the exception in the "else" part of an "if" statement.
  
isNotError, isNotFound are unacceptable.
+
==Layout==
Exception classes SHOULD be suffixed with "Exception" or "Error" .. FIXME (trt) not sure about this?
 
  
Methods returning an object MAY be named after what they return, and methods returning void after what they do.
+
===Function braces ===
  
Files
+
Function braces begin on the line with their operator, and end on their own line indented to the same level.
Class or object-per-file guidelines are not yet determined.
 
  
Tabs (set to 4 spaces) SHOULD be used for indentation.
+
<pre>
 +
foreach my $gene (@genes) {
 +
      print "$gene\n";
 +
                        }
 +
</pre>
  
If your editor supports "file tags", please append the appropriate tag at the end of the file to enable others to effortlessly obey the correct indentation guidelines for that file:
+
<pre>
 +
# YES!
 +
if (@genes) {
 +
    print join("\n",@genes);
 +
} else {
 +
  print "We don't have any genes!\n";
 +
}
  
// vim:ts=4:noet:tw=0:
+
# NO!
The incompleteness of a split line MUST be made obvious :
+
if (@genes)
 +
{
 +
    print join("\n",@genes);
 +
}
 +
else {
 +
  print "We don't have any genes!\n";
 +
}
  
var someExpression = Expression1
+
</pre>
    + Expression2
 
    + Expression3;
 
  
var o = someObject.get(
+
Additional examples follow:
    Expression1,
 
    Expression2,
 
    Expression3
 
);
 
Note the indentation for expression continuation is indented relative to the variable name, while indentation for parameters is relative to the method being called.
 
  
Note also the position of the parenthesis in the method call; positioning SHOULD be similar to the use of block notation.
 
 
Variables
 
Variables SHOULD be initialized where they are declared and they SHOULD be declared in the smallest scope possible. A null initialization is acceptable.
 
Variables MUST never have a dual meaning.
 
Related variables of the same type CAN be declared in a common statement; unrelated variables SHOULD NOT be declared in the same statement.
 
Variables SHOULD be kept alive for as short a time as possible.
 
Loops / iterative declarations
 
Only loop control statements MUST be included in the "for" loop construction.
 
Loop variables SHOULD be initialized immediately before the loop; loop variables in a "for" statement MAY be initialized in the "for" loop construction.
 
The use of "do...while" loops is acceptable (unlike in Java).
 
The use of "break" and "continue" is not discouraged (unlike in Java).
 
Conditionals
 
Complex conditional expressions SHOULD be avoided; use temporary boolean variables instead.
 
The nominal case SHOULD be put in the "if" part and the exception in the "else" part of an "if" statement.
 
Executable statements in conditionals MUST be avoided.
 
Miscellaneous
 
The use of magic numbers in the code SHOULD be avoided; they SHOULD be declared using named "constants" instead.
 
Floating point constants SHOULD ALWAYS be written with decimal point and at least one decimal.
 
Floating point constants SHOULD ALWAYS be written with a digit before the decimal point.
 
Layout
 
 
Block statements.
 
Block statements.
  
 
Block layout SHOULD BE as illustrated below:
 
Block layout SHOULD BE as illustrated below:
while(!isDone){
+
 
     doSomething();
+
<pre>
    isDone = moreToDo();
+
foreach (@items) {
 +
     doSomething($_);
 
}
 
}
 +
</pre>
 +
 
if statements SHOULD have the following form:
 
if statements SHOULD have the following form:
  
if(someCondition){
+
<pre>
 +
if (someCondition) {
 
     statements;
 
     statements;
}else if(someOtherCondition){
+
} elseif (someOtherCondition) {
 
     statements;
 
     statements;
}else{
+
} else {
 
     statements;
 
     statements;
 
}
 
}
 +
</pre>
 +
 
for statements SHOULD have the following form:
 
for statements SHOULD have the following form:
  
for(initialization; condition; update){
+
<pre>
 +
for (initialization; condition; update) {
 
     statements;
 
     statements;
 
}
 
}
while statements SHOULD have the following form:
+
</pre>
 +
 
 +
 
 +
A single statement if-else, while or for MUST NOT be written without brackets, but CAN be written on the same line:
  
while(!isDone){
+
<pre>
    doSomething();
+
if (condition) { statement; }
    isDone = moreToDo();
+
while (condition) { statement; }
 +
for (intialization; condition; update){ statement; }
 +
</pre>
 +
 
 +
<pre>if/unless</pre> conditionals CAN follow the test condition:
 +
 
 +
<pre>
 +
print @genes if (@genes > 10);
 +
</pre>
 +
 
 +
==Whitespace==
 +
 
 +
Conventional operators SHOULD be surrounded by a space (including ternary operators). Excess carriage returns SHOULD NOT be used around braces.
 +
 
 +
<pre>
 +
# YES!
 +
sub my_function {
 +
  my ($self,@args) = @_;
 +
 
 +
  my $string = join(" ", @args) . ': this is an inane example.';
 +
  return $string;
 
}
 
}
do...while statements SHOULD have the following form:
 
  
do{
+
# NO!
    statements;
+
sub my_function {
}while(condition);
+
  my($self,@args)=@_;
switch statements SHOULD have the following form:
+
 
 +
  # Hard to read these lines without space between operators...
 +
 
 +
  my $string=join(" ", @args).': this is an inane example.';
  
switch(condition){
+
  return $string;  
case ABC:
+
  # Why are there carriage returns below here and closing brace? Not necessary.
    statements;
 
    //  fallthrough
 
case DEF:
 
    statements;
 
    break;
 
default:
 
    statements;
 
    break;
 
}
 
try...catch...finally statements SHOULD have the following form:
 
  
try{
 
    statements;
 
}catch(ex){
 
    statements;
 
}finally{
 
    statements;
 
 
}
 
}
A single statement if-else, while or for MUST NOT be written without brackets, but CAN be written on the same line:
+
</pre>
  
if(condition){ statement; }
+
In addition:
while(condition){ statement; }
 
for(intialization; condition; update){ statement; }
 
Whitespace
 
  
Conventional operators MAY be surrounded by a space (including ternary operators).
 
The following reserved words SHOULD NOT be followed by a space:
 
break
 
catch
 
continue
 
do
 
else
 
finally
 
for
 
function if anonymous, ex. var foo = function(){};
 
if
 
return
 
switch
 
this
 
try
 
void
 
while
 
with
 
The following reserved words SHOULD be followed by a space:
 
case
 
default
 
delete
 
function if named, ex. function foo(){};
 
in
 
instanceof
 
new
 
throw
 
typeof
 
var
 
 
Commas SHOULD be followed by a space.
 
Commas SHOULD be followed by a space.
 +
 
Colons MAY be surrounded by a space.
 
Colons MAY be surrounded by a space.
 +
 
Semi-colons in for statements SHOULD be followed by a space.
 
Semi-colons in for statements SHOULD be followed by a space.
 +
 
Semi-colons SHOULD NOT be preceded by a space.
 
Semi-colons SHOULD NOT be preceded by a space.
Function calls and method calls SHOULD NOT be followed by a space. Example: doSomething(someParameter); // NOT doSomething (someParameter)
+
 
Logical units within a block SHOULD be separated by one blank line.
+
Function calls and method calls SHOULD NOT be followed by a space. Example: do_something(arguments); // NOT do_something (arguments)
Statements MAY be aligned wherever this enhances readability.
+
 
Comments
+
Statements and declarations SHOULD be aligned wherever this enhances readability.
 +
 
 +
==Comments==
  
 
Tricky code SHOULD not be commented, but rewritten.
 
Tricky code SHOULD not be commented, but rewritten.
 +
 
All comments SHOULD be written in English.
 
All comments SHOULD be written in English.
 +
 
Comments SHOULD be indented relative to their position in the code, preceding or to the right of the code in question.
 
Comments SHOULD be indented relative to their position in the code, preceding or to the right of the code in question.
The declaration of collection variables SHOULD be followed by a comment stating the common type of the elements in the collection.
+
 
 
Comments SHOULD be included to explain BLOCKS of code, to explain the point of the following block.
 
Comments SHOULD be included to explain BLOCKS of code, to explain the point of the following block.
 +
 
Comments SHOULD NOT be included for every single line of code.
 
Comments SHOULD NOT be included for every single line of code.
Documentation
 
stolen from: Jot wiki
 
  
General Information
+
=User Interface=
These provide descriptions for the function or object:
 
  
summary: A short statement of the purpose of the function or object
+
==Widget and field names ==
description: An extended description of the function or object
 
returns: A description of what the function returns (does not include a type)
 
General Function Information
 
function(){
 
  // summary: Soon we will have enough treasure to rule all of New Jersey.
 
  // description: Or we could just get a new roomate.
 
  //        Look, you go find him.  He don't yell at you.
 
  //        All I ever try to do is make him smile and sing around
 
  //        him and dance around him and he just lays into me.
 
  //        He told me to get in the freezer 'cause there was a carnival in there.
 
  // returns:  Look, a Bananarama tape!
 
}
 
Object Function Information
 
Has no description of what it returns
 
{
 
  // summary: Dingle, engage the rainbow machine!
 
  // description:
 
  //        Tell you what, I wish I was--oh my g--that beam,
 
  //        coming up like that, the speed, you might wanna adjust that.
 
  //        It really did a number on my back, there. I mean, and I don't
 
  //        wanna say whiplash, just yet, cause that's a little too far,
 
  //        but, you're insured, right?
 
}
 
Function Assembler Information (defineWidget/declare)
 
We can sometimes end up in situations where a function declaration is invisible, being created by the call. In this case, there's no way to associate our comments directly with the function. If you encouter this situation, the data can be associated through the passed object.
 
  
Note, this only works if there is no initializer function parameter. If there is, this will be ignored.
+
Widget and field names are specified in the application configuration.  Since these names auto-vivify to actions -- and map to templates of the same name -- choose them carefully.  Likewise, editing them requires changing the name of the template on the file system, too.
  
dojo.declare(
+
Widget names should preferably be short - a single word, and no more than three words. Field names can be more descriptive but no longer than five words.
  "foo",
 
  null,
 
  {
 
    // summary: Phew, this sure is relaxing, Frylock.
 
    // description:
 
    //        Thousands of years ago, before the dawn of
 
    //        man as we knew him, there was Sir Santa of Claus: an
 
    //        ape-like creature making crude and pointless toys out
 
    //        of dino-bones, hurling them at chimp-like creatures with
 
    //        crinkled hands regardless of how they behaved the
 
    //        previous year.
 
    // returns: Unless Carl pays tribute to the Elfin Elders in space.
 
  }
 
);
 
Parameters
 
Simple Types
 
If you're only going to be describing the type of the object, you should do it in the main parameter definition block.
 
  
function(/*String*/ foo, /*int*/ bar)...
+
==Default widgets and fields ==
Type Modifiers
 
There are some modifiers you can add after the type
 
? means optional
 
... means the last parameter repeats indefinitely
 
[] means an array
 
function(/*String?*/ foo, /*int...*/ bar, /*String[]*/ baz)...
 
Full Parameter Descriptions
 
If you want to also add a description, you should move to the initial comment block.
 
  
The format for the general information is: *key *Descriptive sentence
+
===Identification===
  
The format for paramters and variables is: *key ~type~* Descriptive sentence
+
Each class should implement a default "Identification" widget.  This widget is intended to provide the basic information about a given object.  This replaces our non-standard use of Identification, General Information, or General Info in the old structure.
  
Where *key *and ~*type*~ can be surrounded by any non-alphanumeric characters.
+
Each Identification widget should minimally include <code>name</code> and <code>common_name</code>.  You need only include these fields in the configuration file - they will become automatically available to the appropriate controller.  Over-ride <code>common_name</code> in the appropriate model to return the most appropriate common name for an object.
  
function(foo, bar){
 
  // foo: String
 
  //        used for being the first parameter
 
  // bar: int
 
  //        used for being the second parameter
 
}
 
Variables
 
Instance variables, prototype variables and external variables can all be defined in the same way. There are many ways that a variable might get assigned to this function, and locating them all inside of the actual function they reference is the best way to not lose track of them, or accidentally comment them multiple times.
 
function foo(){
 
  // myString: String
 
  // times: int
 
  //        How many times to print myString
 
  // separator: String
 
  //        What to print out in between myString*
 
  this.myString = "placeholder text";
 
  this.times = 5;
 
}
 
foo.prototype.setString = function(myString){
 
  this.myString = myString;
 
}
 
foo.prototype.toString = function(){
 
  for(int i = 0; i < this.times; i++){
 
    dojo.debug(this.myString);
 
    dojo.debug(foo.separator);
 
  }
 
}
 
foo.separator = "=====";
 
Variable Comments in an Object
 
The parser takes the comments in between object values and applies the same rules as if they were in the initial comment block:
 
{
 
  // key: String
 
  //        A simple value
 
  key: "value",
 
  // key2: String
 
  //        Another simple value
 
}
 
Return Value
 
Because a function can return multiple types, the types should be declared on the same line as the return statement, and the comment must be the last thing on the line. If all the return types are the same, the parser uses that return type. If they're different, the function is considered to return "mixed".
 
  
function(){
 
  if(arguments.length){
 
    return "You passed argument(s)"; // String
 
  }else{
 
    return false; // Boolean
 
  }
 
}
 
Still Up for Discussion
 
Pseudo-Code (implemented)
 
  
There are some instances where you might want an object or function to appear in documentation, but not in Dojo, nor in your build. To do this, start a comment block with /*=====. The number of = can be 5 or more. At the moment, this is only useful for declaring an object type that doesn't appear in code.
+
=Documentation=
  
The parser simply replaces the /*===== and =====*/ with whitespace at the very start, so think of these blocks as if they were commented out.
 
  
/*=====
 
module.pseudo.kwArgs = {
 
  // url: String
 
  //        The location of the file
 
  url: "",
 
  // mimeType: String
 
  //        text/html, text/xml, etc
 
  mimeType: ""
 
}
 
=====*/
 
  
function(/*module.pseudo.kwArgs*/ kwArgs){
+
[[Category:Developer documentation]]
  dojo.debug(kwArgs.url);
+
[[Category:Development General (Web Dev)]]
  dojo.debug(kwArgs.mimeType);
+
[[Category: Best Practice (Web Dev)]]
}
 
Using the Doctool locally
 
If you are a developer who has marked their code up using this syntax and want to test to make sure it is correct, you can run the doctool yourself locally. See DocParserInstructions for details on how to do so.
 

Latest revision as of 15:36, 19 June 2014

WormBase Coding Standards and Style Guide

Quick Reference

Entity Format
module CamelCase
method (public) lowercase, multiple words allowed, separated_by_underscores
method (private) _lowercase, multiple words allowed, separated_by_underscores
variable (public)
variable (private)
constant UPPER_CASE

Specific Guidelines

Executables

Scripts must be named according to the function they carry out.

# YES!
build_intermine.sh

# NO!
x

Scripts must have a suffix that denotes their type (BASH scripts: .sh, Perl scripts: .pl, Ruby scripts: .rb).

# YES!
get_gene_ontology.pl

# NO!
build_db

Variables

Variable names should reflect the content of the variable. Be appropriately verbose so that the variable contents are clear.

Abbreviations and acronyms should be UPPERCASE when used as a name:

print_HTML();

CSS variable names SHOULD follow the same conventions as public class variables.

Private class variables should be written using lowercase with a preceding underscore):

sub _my_private_function {
   my ($self,@args) = @_;
   ...
}

Variables with a large scope SHOULD have globally unambiguous names; ambiguity MAY be distinguished by module membership. Variables with small or private scope MAY have terse names.

Public names SHOULD be as clear as necessary and SHOULD avoid unclear shortenings and contractions:

get_BLAST_hits

NOT

gbh();

Iterator variables SHOULD be called "i", "j", "k", etc.

Abbreviations in names SHOULD be avoided.

Variables SHOULD be initialized where they are declared and they SHOULD be declared in the smallest scope possible. A null initialization is acceptable.

Variables MUST never have a dual meaning.

Related variables of the same type CAN be declared in a common statement; unrelated variables SHOULD NOT be declared in the same statement.

Variables SHOULD be kept alive for as short a time as possible.

Hash keys are unquoted unless absolutely necessary. If quotes are necessary, you should change your hash key.

# YES!
$hash{carrot} = 'orange';

# NO!
$hash{'carrot'} = 'orange';

Files

Class or object-per-file guidelines are not yet determined.

Tabs (set to 4 spaces) SHOULD be used for indentation.


Loops / iterative declarations

Only loop control statements MUST be included in the "for" loop construction.

Conditionals

Complex conditional expressions SHOULD be avoided; use temporary boolean variables instead.

The nominal case SHOULD be put in the "if" part and the exception in the "else" part of an "if" statement.

Layout

Function braces

Function braces begin on the line with their operator, and end on their own line indented to the same level.

foreach my $gene (@genes) {
      print "$gene\n";
                         }
# YES!
if (@genes) {
    print join("\n",@genes);
} else {
   print "We don't have any genes!\n";
}

# NO!
if (@genes)
{
    print join("\n",@genes);
} 
else {
   print "We don't have any genes!\n";
}

Additional examples follow:

Block statements.

Block layout SHOULD BE as illustrated below:

foreach (@items) {
    doSomething($_);
}

if statements SHOULD have the following form:

if (someCondition) {
    statements;
} elseif (someOtherCondition) {
    statements;
} else {
    statements;
}

for statements SHOULD have the following form:

for (initialization; condition; update) {
    statements;
}


A single statement if-else, while or for MUST NOT be written without brackets, but CAN be written on the same line:

if (condition) { statement; }
while (condition) { statement; }
for (intialization; condition; update){ statement; }
if/unless

conditionals CAN follow the test condition:

print @genes if (@genes > 10);

Whitespace

Conventional operators SHOULD be surrounded by a space (including ternary operators). Excess carriage returns SHOULD NOT be used around braces.

# YES!
sub my_function {
   my ($self,@args) = @_;
   
   my $string = join(" ", @args) . ': this is an inane example.';
   return $string;
}

# NO!
sub my_function {
   my($self,@args)=@_;
   
  # Hard to read these lines without space between operators...

   my $string=join(" ", @args).': this is an inane example.';

   return $string;   
   # Why are there carriage returns below here and closing brace? Not necessary.

}

In addition:

Commas SHOULD be followed by a space.

Colons MAY be surrounded by a space.

Semi-colons in for statements SHOULD be followed by a space.

Semi-colons SHOULD NOT be preceded by a space.

Function calls and method calls SHOULD NOT be followed by a space. Example: do_something(arguments); // NOT do_something (arguments)

Statements and declarations SHOULD be aligned wherever this enhances readability.

Comments

Tricky code SHOULD not be commented, but rewritten.

All comments SHOULD be written in English.

Comments SHOULD be indented relative to their position in the code, preceding or to the right of the code in question.

Comments SHOULD be included to explain BLOCKS of code, to explain the point of the following block.

Comments SHOULD NOT be included for every single line of code.

User Interface

Widget and field names

Widget and field names are specified in the application configuration. Since these names auto-vivify to actions -- and map to templates of the same name -- choose them carefully. Likewise, editing them requires changing the name of the template on the file system, too.

Widget names should preferably be short - a single word, and no more than three words. Field names can be more descriptive but no longer than five words.

Default widgets and fields

Identification

Each class should implement a default "Identification" widget. This widget is intended to provide the basic information about a given object. This replaces our non-standard use of Identification, General Information, or General Info in the old structure.

Each Identification widget should minimally include name and common_name. You need only include these fields in the configuration file - they will become automatically available to the appropriate controller. Over-ride common_name in the appropriate model to return the most appropriate common name for an object.


Documentation