Getting Started with ColdFusion

5 March 2021

So, what is ColdFusion? I know it sounds a little like something from an episode of Star Trek. Well, simply put, ColdFusion is a rapid web application development platform. What does that mean? Well, it contains two elements. Application server software that runs on your web server and a proprietary tag and function based language, CFML.

ColdFusion is a Server-side language. This means that it requires the user to interact with the server in order for you to make ColdFusion do things for them.

By now, Adobe ColdFusion has been around for over a quarter of a century...which sounds insane when you say it like that. I have been using it since 1997....which also sounds insane. ColdFusion has changed over the years but many things about it remain the same:

How does ColdFusion work? Think of it like this: let’s say you use IIS as your web server. In this scenario IIS will act as the batter in a baseball game. The pitcher is a Web user and ColdFusion is the catcher.

In a typical game, the user pitches an http request for an html page and the batter (that’s the Web server software) hits the request back to the user. With ColdFusion, a user pitches a request for a ColdFusion file. The Web server steps back and let’s the catcher (ColdFusion) take the CFML request and pass it back to the user. I know this analogy is a bit odd but it usually helps illustrate where ColFusion fits into the picture.

Now you may ask, Jack, why should I use ColdFusion instead of another free scripting language like PHP?. The short version is you get what you pay for and ColdFusion, while not cheap, does deliver a boat-load of features that would cost you many times the price of ColdFusion in another free language. There are loads of ColdFusion hosting companies out there if you are looking to run your own website(s) with ColdFusion.

Ok, enough already! Let’s get coding!

CFML is similar to HTML, but what’s the difference between HTML and CFML? Simple. All ColdFusion tags start with the letters “CF”, allowing you to tell what’s static HTML and what’s ColdFusion code. When ColdFusion reads a CFML page and comes across a ColdFusion tag, it performs the specified task, and returns HTML to the end user. One of the reasons that CFML is so powerful is that it works perfectly with existing HTML. Let’s give it a try.

ColdFusion files have the file extension .cfm instead of .htm or .html.

Lesson 1: The Simple Art of CFML

Let’s start this off with the old standby: Hello world.

To set variables in ColdFusion we use the cfset tag like so:



<cfset myMessage = "Hello World!">


The code above effectively creates a variable named myMessage equal to Hello World. Note that we use the standard programming syntax of variable [space] = [space] "value". Why the spaces? It just makes it easier to read. So, now we have a variable. How do we do something with it?


<cfset myMessage = "Hello World">

<cfoutput>#myMessage#</cfoutput>

The cfoutput tag tells ColdFusion Server to process the contents between these tags. By itself, cfoutput is useless, but if you surround your variables and expressions with double pound-signs ##, it becomes the basis for the CFML language structure. Let's try another one:


<cfset firstNumber = 123>
<cfset secondNumber = 456>
<cfset theTotal = firstNumber*secondNumber>
<cfoutput>#theTotal#</cfoutput>

Math with ColdFusion is pretty simple. It uses + for addition, - for subtraction, / for division, * for multiplication, and MOD for the good old modulus operator. Remember that the modulus operator returns the remainder of a division. If, god forbid, you need to raise a number to a specific power you would the carat ^ character. We can use a couple of math functions like pi() and decimalFormat() to do something like calculate the area of a circle like so:


<cfset radius = 12>
<cfset area = pi()*radius^2>
<cfoutput>#decimalFormat(area)# square feet</cfoutput>

Which gives us:

452.39 square feet

Using the modulus operator MOD is pretty simple. It is mostly used to do things like alternate table row colors (before Bootstrap made that even easier) and determine if a number is odd or even.


<cfset someNumber = (100 MOD 4)>
<cfoutput>#someNumber#</cfoutput>

The above would return the number 0 since there is no remainder for that division. That's enough math for now....

Let's try one showing how to concatinate variables together into one output. I'll toss the randRange() function in there to generate a random number too.


<cfset myFirstName = "Jack">
<cfset myLastName = "Poe">
<cfset myNumber = randrange(100,1000)>
<cfset theWholeThing = myFirstName & myLastName & myNumber>
<cfoutput>#theWholeThing#</cfoutput>

The above would output something like the following:

JackPoe231

Why something like? Well, I have a function in there randRange() that creates a random number between 100 and 1000. So each time you reload this page, ColdFusion will generate a different number. Functions are a very powerful and useful part of the CFML language. With randRange() you tell it the low end to start with and the max to end with like randRange(1,9999) and ColdFusion will grab a number between those values. Pretty simple, huh?

There are loads of functions in CFML. Here's one you will use regularly as a programmer:


<cfoutput>#dateFormat(now(),"long")#</cfoutput>

I threw a curve at you there. That is actually two functions nested together. The function now() returns the date and time from the server. The dateFormat() function takes the date and time from now() and formats it with a mask. Specifying long as the mask gives you the long date format of December 9, 2024

You can specify a specific mask like dd-mmm-yyyy instead. Any date format you like, really. You can look at how the masks work here.

That pretty much covers the basics for setting and displaying variables. Let's look at an interesting way to set variables that really functions as a conditional expression.


<cfparam name="myVariable" default="Cheese">

The cfparam tag checks to see if a variable already exists and if not it creates one with the default value you specify. This is really handy when you pass variables from page to page. Let's do that now.


<a href="test1.cfm?myVariable=Beef">Click to select BEEF</a>
<br>
<a href="test1.cfm?myVariable=Chicken">Click to select CHICKEN</a>
<br>
<a href="test1.cfm">Click to select CHEESE</a>

The code within test1.cfm sees the URL variable myVariable in the query string....the part of the URL starting with the ?, and the cfparam says, Oh, that variable already exists so set it to that value. If the variable is not present in the URL it will default to the value specified in the cfparam tag. The third link just goes directly to the page so you can see this in action.

Click to select BEEF
Click to select CHICKEN
Click to select CHEESE

You can actually change the value of the variable in the URL to whatever you like and it will display that value. This is dangerous as it does open things up to possible cross-site-scripting attacks, so you need to be diligent and make sure the values are what they are supposed to be.

ColdFusion reads top to bottom and left to right just like we do, so if the variable doesn't exist ABOVE the cfparam tag then it will set the variable to the default value in the tag.

Note: You cannot place cfoutput tags inside other cfoutput tags. If you do, you will receive an error telling you that you have invalidly nested cfoutput tags. There is a way and reason to do this, but it goes beyond the scope of this simple tutorial. And honestly it doesn't come up very often.

A few more notes about variables in ColdFusion.

  1. ColdFusion is NOT case sensitive. A variable named foo is the same as FOO. It is still good practice to stick to a naming scheme and case and stick with it. Typically we all use the old lowerUpperCase style of naming variables.
  2. ColdFusion variables are typeless. You do not need to specify string or int or anything like that. CF just knows, man. It knows....
  3. Never ever use spaces or punctuation in your variable names... ever. Only an underscore is acceptable.
  4. Your variable name should not start with a number...ever.

You can actually perform calculations inside the double pound signs too.


<cfset x = 12>
<cfset y = 90>
<cfoutput>#x * y#</cfoutput>

You can increment variables too; Like <cfset foo = foo+1"> or you can use standard operators like Or even <cfset foo++> (thanks James!). ColdFusion also has functions to perform this action too. The incrementValue() and decrementValue(), specifically.

You can also concatinate variables like so:


<cfset firstName = "Jack">
<cfset lastName = "Poe">
<cfset userTitle = "Web Guy">
<cfset userInfo = firstName & ' ' & lastName & ' ' & userTitle>
<cfoutput>#userInfo#</cfoutput>

Which will output:

Jack Poe Web Guy

On occasion - and very rarely - you may have a dynamic variable name that you need to process. This one has tripped me up over the years quite often. Thank heavens for code snippets!


<cfset flavor = "vanilla">
<cfset #flavor#_availability = "out of stock">
<cfoutput>#evaluate("#flavor#_availability")#</cfoutput>
<cfoutput>#variables[flavor & "_availability"]#</cfoutput>

We use the evaluate() function to dynamically evaluate a variable value. I have included the bracket notation alternative too because evaluate() is generally discouraged in modern ColdFusion programming. You will see I used another variable scope in there...variables is only required in very specific uses like this. It is the default scope within a page that holds the local variables. Peronally, I never use it unless I have to. The variables scope is implied within the page being accessed already. More on variable scopes below.

The last thing I want to cover here is the cfdump tag. This little gem is a great tool for debugging as you work. You can use the cfdump tag to display ColdFusion variables, objects, and elements when debugging your code. For example:

Want to see what data is being passed when you submit a form?


<cfdump var="#form#">

Need to see what application variables are set in your app?


<cfdump var="#application#">

Need to see the data in a session?


<cfdump var="#session#">

It really is a useful tag and one thing you should know...you can dump and abort the processing of the page at the same time? too! This is a great way to step through your page without executing the whole thing.


<cfdump var="#oldArray#" abort>

Okay, enough about variables. As always, let me know if you have specific questions.

My main mantras for coding are:

Note: Comments in ColdFusion are almost the same as HTML comments.


<!--- your comment here --->

Note that HTML comments use two -- and ColdFusion three ---. HTML comments will cause issues if you are working with JSON.

Note that in some cases you may want to display a pound sign to the user. To do this, you need to "escape the pound sign". This is done by placing two ## together with no information between them. ColdFusion will interpret this as a single character, not a variable to be processed. A simple example of this would be having an HTML color code within a cfoutput. If you have something like #00308F in there it will cause an error because ColdFusion will see the first # and look for it's partner...and there isn't one. You can dodge this by escaping like so: ##00308F. Make sense? And that color code is official Air Force blue.


Lesson 2: Using ColdFusion to Display Database Contents

One of the greatest features of ColdFusion is the amazingly simple way it interacts with databases. CF can tie into just about any database you can think of… Oracle, MS SQL Server, MySQL, MS Access, Sybase, Informix and more!

To work with CF and databases, you need to understand three things. ColdFusion's cfquery tag, the cfqueryparam tag, and SQL.

ColdFusion at it's core uses J2EE (Java 2 Enterprise Edition) and connects to databases with JDBC drivers. That is really more info than you need to connect to a database. You just need the datasource name. Our enviroment at AFIT uses MS SQL Server and Oracle. I will set up a development SQL Server database for you and a development area on our development server so you don't need to install ColdFusion on your workstation. You can install it on your personal or telework laptop if you need to. Ask and I will walk you through installation.

Do you need to know Java to use ColdFusion? No. CFML puts a simple and easy to use language between you and cumbersome Java. However, if you are a Java programmer you can use ColdFusion to communicate with the Java at the core of ColdFusion.

SQL is the basic language that is used to talk to databases. It's a simple language that can make or break you as a developer. I suggest picking up a copy of Learn SQL in 10 Minutes by Ben Forta. This lesson assumes that you don't know SQL very well, though, so I'll keep it simple.

Let's assume you have a database containing one table containing movie info: Movie title, genre, and a review. Pretty basic. Let's pull some info from that table.


<cfquery name="myQuery" datasource="myDSNhere">
SELECT ID, movie_title, movie_genre, movie_review
FROM movie_reviews
WHERE genre = <cfqueryparam value="Comedy" cfsqltype="CF_SQL_VARCHAR"> 
</cfquery>

The cfquery tag is the means by which ColdFusion retrieves data from a database. The attributes we specified, datasource and name, are required by ColdFusion - but datasource can be omitted in certain circumstance - more on that in another lesson. The name attribute of this tag is specified by you, and can be any word that's easy to remember. Query names cannot contain spaces or punctuation just like variables.

Between the opening and closing cfquery tag is the SQL Query itself. This is not CFML, this is SQL, the database language. So just what did we tell the database to do? Simply put, we asked the database to select the comma sparated list of columns we listed from the table "movie_reviews" where the genre is "comedy". ColdFusion then gathers the data from the database and creates a query object named myQuery that contains that information.

You can use a select * to select all of the columns in the table you are selecting from but this is very bad programming. Only select the columns you need. Pulling 30 columns from a database when you need 5 is just asking the query to process slowly. Another reason to avoid the select * pitfall is because when you come back to an app you wrote years before - or you are working with another developer's code - you don't know what columns are being used. You can reverse engineer a select * by dumping one of the three automatic variables that ColdFusion returns with every query: #myQuery.columnNames# will show you a list of the columns returned by the query! Just use that <cfdump var="#myQuery.columnNames#" abort > trick, copy and paste the results over the * and you're good to go.

The other two automatically returned variables associated with a select query are queryname.recordcount which returns the total number of records returned by the query, and currentrow which is the row number for each record returned. I didn't specify the name of the query in that one because normally you use it within query output between the cfoutput tags. Inside a cfoutput query loop using currentrow variable will number each record. Using it with the query name will just display the first number over and over.

The cfqueryparam tag is a powerful tag that helps prevent SQL injection hacking attacks, pre-processes the query, and should ALWAYS be used in every single query wherein you have a "where clause".

You can see the query in it's entirety by using the cfdump tag like <cfdump var="#myQuery#">

Another quick note about ColdFusion queries....you can actually query a query in ColdFusion. I won't get into it too deeply here but if we ran the demo query above and wanted to break down the output into the movies that start with each letter of the alphabet to display them in chunks we can do that with a query of queries like this:


<cfquery name="Amovies" dbtype="query">
SELECT ID, movie_title, movie_genre, movie_review
FROM myQuery
WHERE movie_title LIKE <cfqueryparam value="A%" cfsqltype="CF_SQL_VARCHAR"> 
</cfquery>

This is very powerful and to my knowledge no other programming language will allow you to do this. So, in effect you can pull a query containing everything you need and then break the output up using queries that pull from the "master" query. This is one time that ColdFusion IS case sensitive too. You need to make sure the query name you specify in the query of queries is spelled the same as the name value of the "master" query. Okay, moving on....

One simple note: You see the % in there? That is a wildcard character. In this case, I am asking for all movies that start with "A". This is similar to searching in Windows for file names or types using a * character. Like *.docx will search for all docx files. Some databases allow use the * or the %. The percent sign is universal.

What’s so great about CFML and SQL together, is that you can easily use CFML to augment your query to retrieve exactly the data you need. This means you can actually place CFML within the SQL to make the query do specific things based on whatever conditions you are dealing with. Example: user from department A can only search for Comedy films and user from department B can only search Horror. You could add ColdFusion conditional logic tags to limit who can see what.

Let's go over some conditional logic since it is another of the primary building blocks for all programming.

ColdFusion has three basic ways of performing conditional logic. What is conditional logic? If the sky is blue, do this...if the sky is red, do this...otherwise, do this. That's a pretty basic way of explaining it. Here's the first way to perform


<cfif something IS something>
I will do this if the condition is met
<cfelse>
I will perform this code if the condition is not met
</cfif>

You can also add cfelseif tags in there as well. Just remember cfif comes first, then as many cfelseif tags as you need, with a final cfelse at the end.


<cfset myAge = 48>
<cfif myAge GTE 40>
You are that old?!?  Wow!
<cfelseif myAge LT 40 AND myAge GTE 18>
I wish I was that young!
<cfelse>
You are just a kid!
</cfif>

Note that you don't use standard operators like = or > within the cfif tags. Within those tags you use IS or EQ in place of =. You can also use IS NOT. To check for greater or less than we use GT and GTE as well as LT and LTE. For inequality we use IS NOT or NEQ. Also, the cfelse tag is one and done. You cannot put expressions within the cfelse tag.

Here are a few more ways to use this tag.



<cfif something IS somethingElse>My code here</cfif>
<cfif NOT isDefined('myVariableName')>My code here</cfif>
<cfif myVar IS NOT ''>My code here</cfif>


The second way to perform conditional logic with ColdFusion is using the cfswitch tag. This allows you to feed a variable into the cfswitch and then use cfcase tags to perform the correct bit of code. Here's a simple example.


<cfswitch expression="#eyeColor#">
<cfcase value="Blue">You have blue eyes</cfcase>
<cfcase value="Brown">You have brown eyes</cfcase>
<cfdefaultcase>You have other colored eyes</cfdefaultcase>
</cfswitch>

The third way to perform conditional logic is using the Elvis Operator, AKA the ternary operator. This function allows you to perform conditional logic without a tag....well, just an cfoutput tag, of course. This operator that takes three arguments, hence the name ternary. The first argument is a comparison argument in parenthesis, the second is the result upon a true comparison, and the third is the result upon a false comparison.

The use of inline condition function IIF() is generally discouraged in modern CF programming because it requires use of evaluation functions that can cause security and performance issues. Personally, I am not 100% sure how this would be the case, but on the plus side, the Elvis operator requires less code, so...bonus!

Most of the time we use the old IIF() function to set SELECT options, CHECKBOXES, or RADIO BUTTONS when a user is editing content. On occasion, I have used them to output specific punctuation, etc. in a sentence. While very handy, IIF() has annoying syntax that relies on the delay-evaluation DE() function. DE() has always been a bit of mystery to me but what it does is escape any double quotes in the parameter you feed it and wraps the resulting output with double quotes.

The best way to use DE() is something like:


<cfset myVar = "Jack">
<cfoutput>#de(myVar)#</cfoutput>

Which would give us...

"Jack"

Strange. In 27 years, I haven't ever used DE() outside of the IIF() function.


In the old IIF() function we have to use DE() because IIF() will treat anything in the true/false portion as variable names. Like this:


<cfset thing1 = "Jack">
<cfset thing2 = "Jack is old">
<cfset thing3 = "Jack is young">
<cfoutput>#iif(thing1 IS 'Jack','thing2','thing3')#</cfoutput>

Which outputs a variable if true or false like:

Jack is old

We learn something new every day! I have never used this function in this way. Normally I use it to display text like the following example.

The old way of doing inline conditions using IIF()


<cfset colors = "red,blue,yellow,green,orange,violet">
<cfset myfav = "blue">

<select>
    <cfoutput>
        <cfloop index="i" list="#colors#">
        	<option value="#i#" #IIF(i IS myfav,DE('selected'),DE(''))#>#i#</option>
        </cfloop>
    </cfoutput>
</select>

The new way using the Ternary Operator


<cfset colors = "red,blue,yellow,green,orange,violet">
<cfset myfav = "blue">

<select>
    <cfoutput>
        <cfloop index="i" list="#colors#">
        	<option value="#i#" #((i IS myfav) ? "selected" : "")#>#i#</option>
        </cfloop>
    </cfoutput>
</select>

Sample output

Basic syntax:
#((IF statement Here) ? "If it is true do this" : "If false do this")#

As you can see, the "Elvis" operator is more normal in terms of programming syntax. This is actually the same in C++ which is kind of cool. You will find that several of ColdFusion's functions use similar syntax to visual basic and others.

Okay, that does it for conditional logic with ColdFusion. Let's move on.


Lesson 3: Using CFML to Search a Database

In the beginning of my ramblings that make up lesson two, we used CFML to dump the entire database out to the screen. This works fine for a small database, but in real life it’s rarely useful, and can cause some serious performance problems. The easiest solution is to give users the ability to search the database to find exactly what they need. With CFML this is a snap.

Let's assume you have an HTML form with a field named userSearch. When submitted we want to take the form input and plug it into a cfquery tag to pull the data a user wants to see. Doing this is very simple:


<cfquery name="myQuery" datasource="myDSNhere">
SELECT ID, movie_title, movie_genre, movie_review
FROM movie_reviews
WHERE movie_title LIKE <cfqueryparam value="%#form.userSearch#%" cfsqltype="CF_SQL_VARCHAR"> 
</cfquery>

Now we are inserting the user's input from the form into the query. Notice the %#form.userSearch#%....This has a few points to notice.

  1. The % character in SQL is a wildcard. So here we are saying find the movie titles that contain the user's input. A single % at the beginning of that would find items that start with anything and end with the user input. A % at the end would find matches than start with the user input and end with anything.
  2. Notice the form. in there? That is a variable scope. I mentioned those above. We are telling ColdFusion where to find the userSearch variable. Scopes are a huge part of coding in ColdFusion. They help CF process faster, eliminate ambiguity in variables, and help you tell where things are coming from. There are many scopes in ColdFusion:
    • application - these are used with the application framework which will be explained later.
    • arguments - used in creating custom tags. Yes, ColdFusion lets you create your own tags.
    • attributes - also used in creating custom tags.
    • caller - another custom tag scope.
    • CGI - returns a ton of data about the user, page, and server.
    • cookie - used to access cookies created with the cfcookie tag.
    • form - created when a form is submitted.
    • server - shows the server's version and license info.
    • session - allows you to create and access session variables.
    • this - used within ColdFusion components.
    • variables - the implied scope within the executed page.
    • local - used within user-defined-functions. Yes, ColdFusion lets you create your own functions.

The last part of this is pretty simple. Now we have the query object and we want to display the results in a table for the user to see.


<table>
    <tr>
    	<th>#</th>
        <th>Movie Title</th>
        <th>Genre</th>
        <th>Review</th>
    </tr>
    <cfoutput query="myQuery">
    <tr>
    	<td>#currentrow#</td>
        <td>#movie_title#</td>
        <td>#movie_genre#</td>
        <td>#movie_review#</td>
    </tr>
    </cfoutput>
</table>

Notice that we have added an attribute to the cfoutput tag. The query attribute tells ColdFusion to loop over the query recordset until it runs out of records to display. Keep in mind that doing this with a large set of data can cause a page to load very slowly. To mitigate that you would want to employ pagination. Ask me for help if you need to do that as it is beyond this lesson.

I know I just dumped a TON of info on your here, but there you have it! The basics of ColdFusion and CFML. As you can see, it takes some work, but CFML is a simple and effective way to create any kind of Web application you can think of. As with any programming language, it takes determination, practice, and logical thought process.

As a final note, you can write ColdFusion in several code editors out there. Heck, you can use notepad in Windows if you are into torture. Most of us use Dreamweaver CS6 (code view only) simply because Adobe made the boneheaded marketing decision to remove ColdFusion support from modern DreamWeaver to force developers to buy the absolutely terrible ColdFusion Builder application. Other options are Sublime Text and VS Code. Talk to me about getting one of these on your machine.

-Jack