home Links Articles Books Past Meetings Photos SiteMap
The MDCFUG is sponsored by TeraTech. Visit us at www.TeraTech.com

Please send
comments/questions to

michael@
teratech.com

 

CFML Coding Conventions

7/3/2000

 

 

Variables

 

  1. Specify the scope for all variables.

This makes your code more readable and simplifies debugging since you know where variables are coming from.  If you don’t specify the scope, ColdFusion resolves the name using the following order: CGI, File, URL, Form, Cookie, and Client.  By explicitly defining the scope, you can skip this name resolution step and further improve performance.  Also note that the session and application scopes are not in the name resolution list.  These must be explicitly called.

 

Use lower case for the scope, e.g., session.UserDirectory.

 

2.       Use mixed case for variable names.

Mixed case makes the variable names easier to read.  Always use mixed case for all variable definitions and references.

 

3.       Use descriptive variable names not abbreviations.

If you use descriptive variable names then the code will be much easier for others to read and for you to remember how it works yourself.

 

Note that queries and variables cannot have the same name in the same ColdFusion template page.

 

4.       Match form field names to the corresponding database field name.

This makes it easier for you and others to remember what the field contains.

 

5.       Don’t use pound signs if you don’t need them.

In general, the # signs are needed only when you are referring to variable outside of a CFML tag, and in that case, the text that contains the variable will need to be inside a CFOUTPUT tag.

 

Two exceptions:

a.       If a variable is used inside double quotes.  (Such as when you’re specifying an attribute for a CFML tag.)  The quotes indicate that the name is literal, and you’ll need the pound signs to resolve any variables.

b.       If you're dynamically naming variables, you’ll need to put the variable name in double quotes and use pound signs around the dynamic part of the name. 

 

Otherwise, pound signs should never be used in <CFIF> or <CFSET> tags.

 

To include a pound sign that is not used as a field delimiter, use two consecutive pound signs (##).

 

6.       Use CFLOCK around shared memory variables.

Application, Server, and Session variables are special variables and need to be handled differently then other variables. Because they can be accessed by multiple requests at the same time, every read or write of a variable of this type should be wrapped by the CFLOCK tag. Under ColdFusion 4.5, the SCOPE attribute should be used.

 

Example:

<CFLOCK SCOPE=”Application” TYPE=”Exclusive” TIMEOUT=30>

            <CFSET Application.Foo = 1>

</CFLOCK>

 

<CFLOCK SCOPE=”Server” TYPE=”ReadOnly” TIMEOUT=30>

            <CFOUTPUT>The name of this server is #Server.Name#</CFOUTPUT>

</CFLOCK>

 

For best performance, you should lock every single instance of an application, server, or session variable.

                       

Indention – Indent your code

 

  1. Use white space and indent your code to set off logical code chunks.

This is particularly useful to show the organization of nested tags that contain many attributes or additional tags.  For example, when creating HTML tables …

 

<TABLE Border=”0” Cellpadding=”0” Cellspacing=”0”>

<TR>

<TD>

Table data goes here and is not indented

      </TD>

      <TD>Short text here</TD>

      <TD>

      <TABLE>

      <TR>

            <TD>

                  Nested table data here

            </TD>

      </TR>

      </TABLE>

      </TD>

</TR>

</TABLE>

 

            Indent code inside of CFIF, CFOUTPUT and CFLOOP.  For example …

 

<CFIF … >

      <CFSET … >

<CFELSE>

      <CFSET … >

</CFIF>

 

  1. Keep the line length below 80 characters.

This makes the code easier to read.  Use a return and an indent for continuation lines.

 

  1. Place each attribute to a custom tag on its own line.

When more than one attribute is passed to a custom tag, place each attribute on its own line and indented.  If only one attribute is being used, it may be typed on the same line as the tag call, but may also be indented on its own line.  Place the tag closing bracket (greater than sign) on a line by itself, same indention as opening bracket.

 

Example 1:

<cf_mycustomtag

AttributeOne=”ValueOne”

>

 

Example 2 (Alternate indention for one attribute):

<cf_mycustomtag AttributeOne=”ValueOne”

>

 

Example 3:

<cf_mycustomtagtwo

                  lAttributeOne=”ValueOne”

                  stAttributeTwo=”ValueTwo”

                  bAttributeN=”ValueN”

>

 

This rule is NOT consistent with HTML tag indention rules, but due to the possible complexity of custom tag calls, experience has demonstrated that readability of templates increases when this method is employed.

 

  1. Indent SQL in CFQUERY tags.

Use consistent indention in the SQL in CFQUERY tags to make them more readable.

 

Example 1:

SELECT      TO.ColumnOne, TT.ColumnTwo, TO.ColumnThree

FROM            TableOne TO,      TableTwo TT

WHERE      TO.TableOneID = TT.TableTwoID

AND TT.TableTwoID = 10

ORDER BY      TO.TableOneOrderKey

 

Example 2 (Alternate indention for SELECT):

SELECT

      TO.ColumnOne,

TT.ColumnTwo,

TO.ColumnThree

FROM

      TableOne TO,

TableTwo TT

WHERE

      TO.TableOneID = TT.TableTwoID

AND TT.TableTwoID = 10

ORDER BY

      TO.TableOneOrderKey

 

Example 3:

INSERT INTO

      TableOne

(

ColumnOne,

ColumnTwo,

ColumnThree

)

VALUES

(

‘ValueOne’,

      ‘ValueTwo’,

      ‘ValueThree’

)

 

Example 4 (Alternate indention for INSERT):

INSERT INTO TableOne

(

ColumnOne,ColumnTwo,ColumnThree

)

VALUES

(

‘ValueOne’,  ‘ValueTwo’, ‘ValueThree’

)

 

Example 5

UPDATE TableOne

SET

      ColumnOne = ‘ValueOne’,

      ColumnTwo = ‘ValueTwo’

WHERE

      TableOneID = 10

AND ColumnThree = ‘ValueThree’

 

 

Custom Tags

 

1.       Use Attribute Name Prefixes.

Prepend the appropriate prefix to all Custom Tag attribute names:

 

Type

Prefix

Example Name

Array

a

aMyArray

Boolean

b

bMyBoolean, bChecked, bStable

Date, Time, Date/Time

d,t,dt

dMyDate, tMyTime, dtMyDateTime

Double

db

dbMyDouble

Integer

i

iMyInteger

List

l

lMyList

Number

n

nMyNumber

Query

q

qMyQuery

String

s

sMystring

Structure

st

stMyStuct

WDDX Struct

wst

wstMyWDDXStruct

 

 

  1. Prepend an ‘r_’ to the front of the return attribute name.

For example, r_stProduct.

 

3.       Don’t arbitrarily create or overwrite hard-coded variables in the CALLER scope.

Pass the name of the return variable into the custom tag.  The custom tag can then modify the contents of the return variable.  If you have multiple return values, return them in a structure, e.g., r_stProduct.

 

  1. Include comments at the top of the Custom Tag file.

Comments are described below, in the General section.  Use the naming conventions described above for the attributes to the Custom Tag.  Prepend an ‘r_’ to the front of the return attribute name, e.g., r_stProduct.

 

 

General

 

1.       Use upper case for all tag names and lower case for the attribute names.

Using upper case for the tag names makes them stand out.  For example:

 

<FONT face=”Arial Black” size=”+2”>Title of the page</FONT>

 

Quote all values within the tag.

 

  1. Use boolean expressions in CFIF tags.

CFIF tags will evaluate 50% faster if they are expressed in terms of the boolean values returned by built-in ColdFusion functions instead of the more-obvious string comparisons.

 

EXAMPLES:

Instead of:

<CFIF MyVar IS NOT “”>

<CFIF MyVar IS “POST”>

<CFIF MyVar IS NOT 0>

Do this:

<CFIF Len(Trim(MyVar))>

<CFIF NOT Compare(MyVar,”POST”)>

<CFIF MyVar>

       

3.       CFOUTPUT is faster than CFLOOP.

If you’re looping through a query, it’s much faster to use CFOUTPUT then to use CFLOOP. 

 

4.       Validate variables before using them in the template.

If you are accepting URL, Form, or Cookie variables from the client, make sure you verify that they’re in the proper format before using them in your template.  Not only does this vastly improve error-handling, but there are also security considerations to blindly dumping strings into a database.

 

<CFPARAM name=”form.NumericFieldName” value=”0” type=”Numeric”>

 

5.       Write portable code.

To ensure that your applications can be ported over other ColdFusion platforms or onto client servers, use these conventions:

·         Lower case all filenames and references to these filenames that are used in URLs.

·         For pre and post execution files, name them “Application.cfm” and “OnRequestEnd.cfm”  (Unix is case-sensitive!)

·         Never, ever hardcode pathnames.  Use CFML path functions -- such as ExpandPath() -- to get an absolute path that is relative to the template’s location.  If you absolutely must hardcode a path, define this as an Application-scoped variable in the Application.cfm file.

·         Use the URLEncodedFormat function if you are passing dynamic parameters that may contain spaces.  This prevents the server from getting an error or truncating the URL at the first space.

 

6.       Validate your input.

Make sure that you’re validating your data from form or url inputs before putting it in the database.  Things to look out for are data types, minimum and maximum lengths, and date formats.

 

7.       Use the CFSWITCH statement in place of CFIF…CFELSE to repeatedly check the same variable for different values.

For Example:

 

<CFSWITCH expression=”#intYrsService#”>

   <CFCASE value=”1”>

      <CFSET Message = “One!  One year of service.”>

   </CFCASE>

   <CFCASE value =”2”>

      <CFSET Message = “Two!  Two years of service.”>

   </CFCASE>

   <CFCASE value =”3”>

      <CFSET Message = “Three!  Three years of service.  Ah.”>

   </CFCASE>

</CFSWITCH>

 

8.       Calling functions that directly manipulate variables.

Some functions in CF will directly manipulate variables and then return a boolean value.  If you don’t need the return value of these functions, you don’t need to initalize a dummy variable.  Similarly, if you’re performing multiple queries SQL inserts or updates, you don’t need to dynamically name the queries.

 

<CFSET StructDel(jedi,”anakin”)>

 

9.       Put frequently used code into custom tags.

Although it’s much easier to copy and paste your code where you need it, you’ll save time in the long run (and save another developers sanity) by encapsulating this code into a custom tag and calling it where need be.  The concept here is similar to that for writing COM objects, but it’s much simpler to implement.

 

10.   Include comments at the beginning of each file.

Include comments at the beginning of each template or Custom Tag that includes the following information:

·         File name

·         Author’s name

·         Date written

·         Description of the template or Custom Tag

·         List of attributes (Custom Tags only):

·         Name

·         Description

·         Required/Optional

·         Error return codes (where applicable, Custom Tags only):

·         Return code

·         Description

·         Thrown errors (where applicable):

·         Type

·         Error code

·         Description

·         History of changes made to the code with the date, author and description of the change, from oldest to most recent.

 

11.   Include embedded comments in the code.

Include CFML comments (<!--- --->) before each block of code or before code that needs to be explained.  Basically if when you return to the code after a couple of weeks absence and you have to figure out what is does, put in comments.

 

12.   Avoid Whitespace.

Use CFSETTING with the ENABLECFOUTPUTONLY attribute to cut whitespace out of the page ColdFusion returns to the browser.

 

13.   Perform Error Checking.

Use the CFTRY and CFCATCH tags for operations that are somewhat likely to fail, such as around expensive queries, when connecting to flaky COM objects, etc.  This will allow you to customize errors or specify work-arounds for these specific problems.  For general error-catching purposes, use the CFERROR tag in the Application.cfm file to specify a general error template that can replace ColdFusion errors.

 

14.   Cache relatively persistent data.

Caching has been available in ColdFusion since the advent of Application and Session collections.  For example, if you’re reading data out of a file in your application, you can set the contents of this file read to an Application or Session variable to save the webserver from time-costly CFFILE reads.

 

However, with the release of CF 4.0, Allaire has made caching much easier by integrating query-level and page-level caching into their language.

 

Recordsets can be cached using the CACHEDWITHIN attribute of the CFQUERY tag.  This is helpful with queries that seldom change, for example lists of states and state abbreviations.  Caching these queries saves trips to the database, which the amount of time your application spends talking to an external component.

     

      If the dynamic content on your page changes infrequently, you can cache the entire page using the CFCACHE tag.  Note, however, that pages are cached across the entire application; you can’t use page-level caching if the page contains data that is user-sensitive.  Also note that if you’re debugging an application, you’ll need to remove page-level caching and then remember to add it before you redeploy.  Save yourself some time by wrapping your CFCACHE tag with conditions:

 

<CFIF NOT IsDebugMode()>

   <CFCACHE timeout=”#DateAdd(“h”,”-4”,Now())#”>

</CFIF>

 

15.   Pages with forms should post to themselves.

The best way to handle forms in terms of user interface and consistency is to have all forms post to the same page they originate on.  Then at the top of that page, have some code to check if the current page is being loaded as the result of a form submission and if so, do any error checking and database processing, then CFLOCATION or CFINCLUDE to the next page in the sequence.

 

This method has several advantages:

·         If you post to the next page in the sequence and do your database processing there, and the user hits reload on that page, the form is resubmitted, and the database processing happens again.

·         Using this method, you can pre-fill the form fields with #form.Fieldname#.  This means that the first time the page is loaded, the fields will be empty, but if there's a validation error, you can just display the error message along with the same form over again, with all the values the user entered already there.  Then, the user has only to change what they previously entered and submit the form again to correct their error.

·         It just makes more sense.  You have a form and the code that processes that form on the same page.  From a maintenance perspective, this is much easier to deal with.

 

 

Directory / File Naming Conventions

 

  1. Use lower case for all directories and file names used in a URL.

 

2.       Use mixed case for all Custom Tags, Handlers, etc, file names.

Mixed case file names are easier to read than all lower case.  All of the mixed case file names must be defined and referenced with mixed case.

 

3.       Create a separate directory for Custom Tags, Handlers, PLPs, etc under the site root directory.

Create a separate directory under the site root directory for Custom Tags, Handlers, PLPs, etc.  This collects all of the files for a site in one place.  By default Spectra sets up directories to store these files under /Program Files/Allaire/spectra/.  For example, the default location of the handlers files for the BookSeller project is:

 

            /Program Files/Allaire/spectra/handlers/BookSeller/

 

The above convention assumes that there is only one site, or a limited number of sites on the machine.

 

Add the project Custom Tag directory to the registry entry HKEY_LOCAL_MACHINE/SOFTWARE/Allaire/ColdFusion/CurrentVersion/CustomTags/CFMLTagSearchPath.  Separate the directories with a comma.  The directories will be searched for the Custom Tag in the order listed.

 

If you have a large number of handlers or want to group the handlers by ContentObject Type, then create a directory under the Handlers directory for each ContentObject Type.  If the handlers are overrides for the default Spectra handlers, e.g., create, edit, or display, place the override handlers in separate directories which are named for the ContentObject Type.  This is needed since the file name for the override handler is the same for all of the ContentObject Types.

 

4.       Create a separate directory for each major function of the site.

Create directories for the major site functions under the site root.  This allows you to group the files into smaller groups, making them easier to find and maintain.  If the site is very large or contains a logical hierarchy to the functions, create subdirectories for the functions under these directories.

 


Home | Links | Articles | Past Meetings | Meeting Photos | Site Map
About MDCFUG | Join | Mailing List |Forums | Directions |Suggestions | Quotes | Newbie Tips
TOP

Copyright © 1997-2024, Maryland Cold Fusion User Group. All rights reserved.
< >