cfscript

# CFScript documentation

This attempts to document all of CFScript, as a resource for people migrating from old-school tag-based code to script-based code. The reason I am doing this is because neither ColdFusion nor Railo/Lucee provide much (or in the case of Railo/Lucee: any) useful documentation of CFScript.

This is not a document for converting tags to script. It is not written from a point of view of “if you use <cfsometag> then you need to instead use [some script construct]”. It simply documents CFScript.

There are some syntax-neutral solutions to some CFML constructs which are listed at the bottom of the document. These are the CFCs found in [customtag]/com/adobe/coldfusion. These are not CFScript constructs per se, but related enough to be relevant here.

It is also not an exercise in teaching CFML (or at least the script part). It assumes you know what you’re doing, and is purely a reference.

I assume Railo 4.2/Lucee 4.5 or ColdFusion 11, except where stated.

In this case, the commented bit is /* multiple line /* comments */ , making the next bit a syntax error.

## Statements

Statements end in semi-colons:

Semi-colons are generally optional on Railo/Lucee:

Where “generally” means “if the end of the statement is unambiguous without a semi-colon”. It is better to just always use semi-colons.

Block statements (with curly braces) do not have semi-colons:

## Variables

Assigning a variable:

Assigning a function-local variable:

Note that the var keyword can appear inline in most statements where a variable is first initialised, eg:

Assigning a dynamically-named variable:

Run this example on trycf.com

This is the same as with a <cfset> tag, but confuses some people due to it being slightly odd-looking. Obviously one can also use associative array syntax too (eg: variables[varName] = "bar"; . This is preferable as it’s more clear what’s going on).

Defaulting a variable:

For more complex situations:

## Operators

All operators available to tag-based code still work in CFScript. In addition, CFScript has these ones:

### Decision

Run this example on trycf.com

### Arithemetic

#### Increment/decrement

Run this example on trycf.com

#### Inline assignment

Run this example on trycf.com

### Boolean

Run this example on trycf.com

### Decision

#### Ternary operator

Run this example on trycf.com

Run this example on trycf.com

#### Null-coalescing variation

Run this example on trycf.com

Run this example on trycf.com

Note that whilst this appears to be the same as other language’s “Elvis” operator, it is not the same. The “Elvis” operator checks for false (and in some languages null is falsey); this operator checks specifically for null . This is likely due to a misunderstanding one the part of Adobe (and perpetuated by the Lucee devs when copying it).

## Conditions

### if/elseif/else

Run this example on trycf.com

### switch

Run this example on trycf.com

## Iteration

### General-purpose for loop

or:

EG:

or:

The general perception is that this is the only form of a general-purpose for() loop: initialising a counter variable, testing it and adjusting it (increment, decrement). This is not the case. Each of the statements can be anything (the condition needs to evaluate to a boolean), and indeed are optional. This is an endless loop, equivalent to while (true):

A very contrived example to demonstrate the freedom one has with the parameters of the for():

In general, all looping constructs have either the single-statement or block-of-statements syntax. I’ll only offer the more common (and recommended, for code-clarity) block syntax henceforth.

### Pre-condition loop

This form of loop evaluates a single condition at the beginning of each iteration, and continues to loop whilst the condition is true:

This form of loop will execute zero or more times.

### Post-condition loop

This form of loop evaluates a single condition at the beginning of each iteration, and continues to loop whilst the condition is true:

This form of loop will execute one or more times. It’s important to consider that the body of the loop will always run the first time, because no condition is evaluated until the end of the loop.

### Array loop

#### Array.each()

Note that Railo/Lucee can call methods directly on a literal, so this works:

### Query loop

Using grouping:

Railo/Lucee only:

### List loop

I am not sure how one would specify a delimiter for the last example: it does not seem supported.

Railo/Lucee only:

### File loop

Railo/Lucee only:

### Date/time range loop

ColdFusion has no specific CFScript-specific construct for this as of ColdFusion 11

Work around:

Railo/Lucee only:

cfcontinue:

## Components / interfaces

### Attributes

Or:

Note that the comment for annotations is /** not simply /* .

Also note that the latter syntax does not currently work on Railo (see RAILO-3169).

Basic:

### Functions

Basic:

With access and return type modifiers:

Basic:

Type:

Required:

Default value:

### Function/argument annotations

Note these annotations do not current correctly work on Railo (see RAILO-3170)

Also note that this does not currently work on ColdFusion (see 3808960)

### Function expressions

Functions defined by function expressions use closure, functions defined by a function statement do not

Annotations for function expressions are not supported on ColdFusion (3808978); are supported on Railo, but have same shortcomings as noted above.

### Calling functions dynamically

Railo/Lucee-only:

## Database

### Query

To qualify parameters with SQL types you can specify the equivalent of the cfqueryparam options with the parameters in the following way:

For versions prior to ColdFusion 11 (in which queryExecute() was implemented), there is a CFC-based solution: Query.cfc. An example is as follows:

### Stored Procedure

Railo/Lucee only

There is a change request you should vote for, to implement this syntax:

See ColdFusion ticket: 3791737; Railo ticket: RAILO-3184, and earlier blog article: ‘ColdFusion 11: calling a stored procedure from script. And can we please stop wearing out our “c” and “f” keys?’.

### Insert

Railo/Lucee only:

Note: there is a bug with this: RAILO-3180.

ColdFusion only:

Note that datasource is currently required, which is a bug: 3814079.

### Update

Railo/Lucee only:

Note the same bug applies here as does with insert.

ColdFusion only:

### DB Info

Railo/Lucee only:

### Transactions

Note that all attributes of <cftransaction> are supported as space-separated name/value pairs.

## Debugging

### Dump

With named arguments:

Railo/Lucee only:

## General / Miscellaneous

### Output

Railo/Lucee only:

### File Encoding

Note that this only works in CFC files on ColdFusion (3712167). It works correctly on Railo/Lucee.

### Image / XLS manipulation

The function equivalents of <cfimage> and <cfspreadsheet> are all well documented, and are not specifically CFScript constructs.

### PDF Manipulation

I have to concede I have never ever done any work with PDFs, so cannot make an informed comment on the CFScript equivalents. However in lieu of particular CFScript-specific constructs that I am aware of, the generic syntax ought to work, eg:

ColdFusion:

Railo/Lucee:

The same should work on other PDF-oriented tags. For versions of ColdFusion prior to CF11, there is a PDF.cfc (similar to Query.cfc, and also in cfusion/CustomTags/com/adobe/coldfusion). I have never used it, do not know how it works, and have no interest in finding out. If someone would like to donate some example code, I will integrate it here.

## Elements of tag-based CFML with no specific CFScript implementation

### CFC-based solutions

As far as I can tell, there is no CFScript-specific implementations for the following pieces of functionality:

• <cfftp>
• <cfpop>
• <cfimap>
• <cffeed>
• <cfldap>
• <cfcollection>
• <cfindex>
• <cfsearch>

There are CFC wrappers for these in cfusion/CustomTags/com/adobe/coldfusion. These are not CFScript-specific solutions per se - one can just as easily use them in tag-based code - but can be included here for the sake of completeness. I personally do not use these constructs, and as they are not part of CFScript, did not attempt to include them here. Feel free to document and include them if you so choose.

### http.cfc

ColdFusion (CF9+):

The pattern seems to be set{ATTRIBUTENAME}( value ); for setting attributes that are normally set via the <cfhttp> tag

### mail.cfc

ColdFusion (CF9+):

The pattern seems to be set{ATTRIBUTENAME}( value ); for setting attributes that are normally set via the <cfmail> tag

### The rest

To use any other functionality not listed here within CFScript, one needs to use the generalised syntax.

On Railo/Lucee this is a matter of removing the " <cf " and the " > ", and using normal block syntax (curly braces) where the tag-version is a block-oriented tag.

On ColdFusion (CF11+), replace the " <cftagname " with " cftagname( ", and the " > " with " ) ", and comma-separate the attributes. Note that this will make the construct look like a function, but it actually is not, and cannot be used like a function, eg this is invalid syntax:

Some tags take a block of code / text within them. Blocks are represented with curly braces, similar to a flow-contrl statement.

Note how text needs to be “output” using writeOutput . Note also how sub-tags ( cfmailpart here) are also expressed using the same rules as parent tags.