ColdFusion 9 Developer Tutorial

5 (2 reviews total)
By John Farrar
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Web Pages—Static to Dynamic

About this book

Adobe ColdFusion is an application server, renowned for rapid development of dynamic websites, with a straightforward language (CFML), powerful methods for packaging and reusing your code, and AJAX support that will get developers deep into powerful web applications quickly. However, developing rich and robust web applications can be a real challenge as it involves multiple processes.

With this practical guide, you will learn how to build professional ColdFusion applications. Packed with example code, and written in a friendly, easy-to-read style, this book is just what you need if you are serious about ColdFusion.

This book will give you clear, concise, and practical guidance to take you from the basics of ColdFusion 9 to the skills that will make you a ColdFusion developer to be reckoned with. It also covers the new features of ColdFusion 9 like ORM Database Interaction and CF Builder.

ColdFusion expert John Farrar will teach you the basics of ColdFusion programming, application architecture, and object reuse, before showing you a range of topics including AJAX library integration, RESTful Web Services, PDF creation and manipulation, and dynamically generated presentation files that will make you the toast of your ColdFusion developer town.

This book digs deep with the basics, with real-world examples of the how and whys, to get more done faster with ColdFusion 9.

Publication date:
July 2010
Publisher
Packt
Pages
388
ISBN
9781849690249

 

Chapter 1. Web Pages—Static to Dynamic

In this chapter, you will learn how to enhance basic HTML pages with the power and simplicity of ColdFusion. Here, we will use what we are learning to build a simple FAQ (Frequently Asked Questions) web application. We will cover the following skills in the process:

  • Moving from HTML to dynamic web pages

  • Simple and structured variables

  • URL and CGI variable structures

  • Setting default variables for pages

  • Debugging and exception handling basics

  • How lists and arrays work in ColdFusion

  • How to cycle through collections with looping commands

  • Conditional processing

 

Turning HTML into a dynamic web page


Let's jump right in and take a look at the difference between common HTML pages and the power of a server-side language. We will leave out the "designer side" of web pages for now. This is again because we are going to focus on pragmatic programming concepts with ColdFusion.

Note

Visit this book's site at http://books.sosensible.com/index.cfm/books/ for help with things such as installing ColdFusion. If you go to this book's home page, there is also a link to the ZIP file for this book's code.

HTML requests

Let's work through some examples. Copy the tutorial/chapter_1 directory from the book's code bundle to the cfb/chapter_1 directory inside your server root. Enter http://localhost/cfb/complete/chapter_1/1_1.htm into the address bar of your browser. You will see a basic FAQ page as follows:

You should open the View Page Source from the browser and compare that to the code you see if you open the file in an editor. You will find that the pages are the same in every way. Here you will see how a normal server returns common HTML pages:

When we add ColdFusion to a web server, we get an extra step in how the pages are managed. This is why we are now able to create pages that are made dynamic from the server side of the equation. This is the same concept for all server-side languages.

Now let's get into a very basic introduction to ColdFusion. We will take this one step at a time. Here is the same code segment with common HTML. If you type this into an HTML page and load it into the browser, it will look the same in code as it does in the view source from the browser:

<!-- Example: 1_1.htm -->
<!-- HTML Comment -->
<div>
  <h3>Question: What is a variable?</h3>
  <p>
    <strong>Answer:</strong>
  </p>
  <p>
    Variables are named storage containers inside programming languages. Just think of variables as any type of named container holding any type of stored content. You simply name the container and store the content. Later you retrieve the content by using the same name.
  </p>
  <p>12:53 PM</p>
</div>

This is a screenshot of the previous html code running in the browser:

ColdFusion requests

Now we will look at a little more dynamic version of the page. The changes will be indicated so we can start to see what ColdFusion adds to the mix. You may be able to tell what is going on without any help depending on your programming background.

Copy the file named 1_1.htm and save the copy as 1_2.cfm in the same directory. Go back to the browser and this time look at this web page: http://localhost/cfb/chapter_1/1_2.cfm. You should note that this page looks the same and the code is basically the same if you use the browser view source.

Comments

We are going to add the following two lines above <!-- HTML Comment -->:

<!--- Processing --->
<!--- Content --->
<!-- HTML Comment -->

You will notice the two new lines have three dashes instead of two. This is because they are ColdFusion comments.

If you go back to your browser and refresh the page, you will find something interesting when you view its source. The new comment lines you added do not show on the page source since they are server-side ColdFusion comments. Remember to save the file before checking for results.

Next we need to create our first variables in ColdFusion. Add a line between the processing and content comments and create the following two variables inside <cfset> tags. These variables are just containers to store content for later use. Currently, we will be using them as text containers or what you will come to know as "string variables".

<!--- Processing --->
<cfset myQuestion = "">
<cfset myAnswer = "">

<!--- Content --->

Cut the actual question out of the bottom content section and paste it into the quotes of the string variable, myQuestion. Now, cut out the answer text in the content section and paste it inside the quotes of the string variable, myAnswer. (Don't forget, you can look at the previous code example if you have questions.)

Variable output

Now, we need to put the content, which we have moved to variables, back in the page. ColdFusion was the first to standardize server-side code tags. These look very much like HTML tags, but they add power and simplicity. What we need to do is wrap our entire content section with <cfoutput>. Add <cfoutput> open tag right after the <--- Content ---> comment tag and then put </cfoutput> close tag as the new last line of the code page.

We have to place the variables in the content section of the code with some special ColdFusion output markers. ColdFusion uses the pound symbols on both sides of the dynamic content for markers. So put #myQuestion# where you cut out the content for the myQuestion variable.

Also, place #myAnswer# where you cut out the content you pasted into the myAnswer variable. Save the file and run the page! (Check the sample code in the following section to make sure you typed things in correctly. Then refresh the page again.)

Functions

ColdFusion is very powerful and allows outputting the results of functions as well as variables. If you want you can replace the time with the function in the following code at the end of the ColdFusion code sample and you can refresh the page over and over and see that the time is being dynamically generated on the server:

<!--- Example: 1_2.cfm --->
<!--- Proccessing --->
<cfset myQuestion = "What is a variable?">
<cfset myAnswer = "Variables are named storage containers inside programming languages. Just think of variables as any type of named container holding any type of stored content. You simply name the container and store the content. Later you retrieve the content by using the same name.">

<!--- Content --->
<cfoutput>
  <div>
    <h3>Question: #myQuestion#</h3>
    <p>
      <strong>Answer:</strong>
    </p>
    <p>
      #myAnswer#
    </p>
    <p>
      #timeFormat(now())#
    </p>
  </div>
</cfoutput>

The now() function in ColdFusion returns the current date or time and the timeFormat() function converts the output to display text showing the time of its contents. Notice that when we update the screen, the time will be the current time on each refresh:

Congratulations! You have just created your first dynamic web page. If you are new to this technology, then work through the examples and complete the entire chapter. Then take a break. If you feel the need, come back after going through some chapters and repeat the exercises. You will be surprised by what you have learned.

Note

We will be removing the <html></html> standard wrappers from most examples going forward in this book. Browsers don't need those markers to present the content. In your live site code, however, those should be included.

 

Understanding and using simple variables


In this section, we will look at a couple of variable types which will help you understand how ColdFusion works. First we are going to look at the different types of simple variables.

Variable types

There are four types of simple variables. These are string, numeric, Boolean, and date/time variables. They can basically have any name for a variable, but there are a few basic guidelines for naming variables:

  • A variable name must begin with a letter, which can be followed by any number of letters, numbers, and underscore characters. (We have found that you can start variable names with underscore also and there is enough code out there that it is unlikely to see this depreciated, if you use it.)

  • A variable name cannot contain spaces.

  • Variable names are not case-sensitive in ColdFusion. (myVariable is the same to ColdFusion as Myvariable.)

Integers

We will be covering two number classes in this lesson. First we will take a look at integers. These are numbers with no decimal value. ColdFusion supports integers between -2,147,483,648 and 2,147,483,647. It will work with numbers outside this range, but the precision will not be exact.

In the first example, we will modify the code we have been using to keep one of the string variables and add a numeric variable called myAge. The following two examples of code run identical to each other. It is fine to code via tag or scripted code:

Tip

Remember to run the code examples as you go. It enhances understanding and retention.

<!--- Processing --->
<cfset myQuestion = "This is my question.">
<cfset myAge = 27>

<!--- Content --->

<!--- Content --->
<cfoutput>
  myQuestion is (#myQuestion#)<br />
  myAge is (#myAge#)<br />
</cfoutput>

<!--- Processing --->
<cfscript>
  myQuestion = "This is my question.";.";
  myAge = 27;
</cfscript>

<!--- Content --->
<cfoutput>
  myQuestion is (#myQuestion#)<br />
  myAge is (#myAge#)<br />
</cfoutput>

Note

Note that when writing script, commands and assignments are completed by the use of a semicolon.

Strings

You will notice that strings are declared with quotation marks. These can be single or double quotation marks. Numbers do not use quotation marks. This would be the same in an expression, which is what you see in the preceding examples, as in a variable declaration. Expressions are what we call code when we combine strings, do math, or Boolean comparisons. Here we will look at our first expression example by changing both the string and the numeric variables in our code. ColdFusion 8 added the += operator to the platform. This is a widely used notation to say, add the right-hand value to the original value. (It also added &= for strings.) Run the following example:

<!--- Example: 1_3.cfm --->
<!--- Processing --->
<cfscript>
  myQuestion = "This is my question.";
  myAge = 27;

  myQuestion = myQuestion & " Is this a string?";
  myAge += 1;
</cfscript>

<!--- Content --->
<cfoutput>
  myQuestion is (#myQuestion#)<br />
  myAge is (#myAge#)<br />
</cfoutput>

The following screenshot shows the result after the previous code is run:

Note

There is no requirement to write things in CFScript like you will see in this book. Currently, script is used in JavaScript, AIR/Flash/Flex ActionScript, .Net, PHP, and JAVA. This is likely the most common form of coding.

Decimals

Now, we will look at decimal-based numbers. We will modify the code just a bit more to show more of the things you can do with numbers and remove the string functions for the time:

<!--- Example: 1_4.cfm --->
<!--- Processing --->
<cfscript>
  myAge = 27;

  halfAge = myAge/2;
</cfscript>

<!--- Content --->
<cfoutput>
  myAge is (#myAge#)<br />
  halfAge is (#halfAge#)<br />
  halfAge rounded is (#round(halfAge)#)<br />
  4.2 rounded is (#round(4.2)#)<br />
  4.2 ceiling is (#ceiling(4.2)#)<br />
</cfoutput>

Here we see variables and functions both being inserted into the HTML rendered by the browser:

Additional functions

We have looked at creating a variable by using the value of another variable and changing the values of variables. You will find everything from modulo functions to geometry functions standard for mathematic calculations. You will also find a rich number of string functions that can help you process your pages.

What additional types of things can you do with strings? Let's take a look at a piece of code that will help answer that question:

<!--- Example: 1_5.cfm --->
<!--- Processing --->
<cfscript>
  myQuestion = "This is my question.";

  myQuestion = myQuestion & " Is THIS a string?";
  location = find("this",myQuestion);
</cfscript>

<!--- Content --->
<cfoutput>
  myQuestion is (#myQuestion#)<br />
  Location of "this" is (#location#) characters from the start of the string.<br />
</cfoutput>

Here we see results that let us know our search was not successful:

Find and FindNoCase

You might be curious as to why the find function returned zero rather than the actual position. If you look, you will notice that we changed the word this to all capitalized letters. Computers see capitalized letters differently than lowercase letters, so THIS provided an excellent way to make a point on strings being case-sensitive. Let's see how we can find it either way with a built-in ColdFusion function:

<!--- Example: 1_6.cfm --->
<!--- Processing --->
<cfscript>
  myQuestion = "This is my question.";

  myQuestion = myQuestion & " Is THIS a string?";
  location = findNoCase("this",myQuestion);
  location2 = findNoCase("this",myQuestion,location+1);
</cfscript>

<!--- Content --->
<cfoutput>
  myQuestion is (#myQuestion#)<br />
  Location of "this" is (#location#) characters from the start of the string.<br />
  The second "this" is located at position (#location2#).<br />
</cfoutput>

In the following screenshot, we can see that the search function was a success and realize the importance of being case-sensitive aware in text searching:

We did a couple of things here. First, we made our string search case-insensitive. Then, we added a second search to see if there were any more occurrences of the searched for item in the string variable. We added +1 to the location to make sure we skipped that location in our search. It still returns the location based on the start of the string no matter how deep we start in our search. Here is the structure of the function so you can understand how function documentation works when you look things up:

FindNoCase(substring, string, [start])

The arguments of the functions are required unless they are wrapped in [ ]. This function searches for a substring inside of the string optionally starting at start number of characters deep into the string.

Tip

Do not confuse the [ ] for the array notation. When looking at code docs, this only means an optional parameter.

 

Understanding structures


Now we are going to shift to understanding the concept of structures. Structures are one of the first of the most powerful variables we will be looking at in this book. This is an example of how structures work. Don't use it for more than an illustration. Structures are like folders and files on a computer file system. Folders can be empty or contain multiple files or nested folders. The files can contain different types of content.

Structures in ColdFusion work along the same concepts. Your structures can be empty or contain both additional nested structures and/or variables holding data.

There are two types of structures that we will initially look at: CGI and URL.

CGI variables

Let us look at our first built-in structure type. It is called CGI. We will also take a look at the most commonly used debugging tool for many developers. CGI is a collection of variables that gives details about things ranging from the current request and the browser of the requesting user, to information about the current running server. Although it doesn't tell us everything, it does provide good information that we may visit over and over again. All structures start with a base structure element. It should be no surprise that the CGI structure starts with cgi followed by a dot ( . ) with the structure variable name.

cgi.structure_item_name

Let's look at an easy way to see what is available. If you do this yourself, you can scroll through and see how much information it offers. The following is the simple code. You will also note that the pound symbols surround the variable name. This is required for functions to work right. Don't worry if it seems odd at first; you will pick it up pretty fast even if you don't get it at first glance.

<!--- Example: 1_7.cfm --->
<!--- Processing --->
<!--- Content --->
<cfdump var="#cgi#">

The <cfdump> tag in ColdFusion takes any complex data type and creates a grid or nested grid if there is nested structure to display the contents of the variable. Dump allows us to see the state of a variable structure at a fixed point in the processing cycle of our web pages. There are options to not expand and also to give a label to the dump for occasions when we may put more than one dump on a page during our programming cycle. It should be noted that we don't want to use this type of function on final production code because for some reason users always think that this means the system has crashed. There is also a possibility to expose information that we did not want to make public. Look at the end of the page; we can see the server port, if the port was secure, and many other details with this dump:

You will see everything from server variables to the remote address of the requesting user. If you were to access these directly in the code you would do it like this. You will notice that the structure cgi contains a good number of variables. In this case, there is no nested structure but only variables. This makes for a better introduction to structures:

<!--- Example: 1_8.cfm --->
<!--- Processing --->
<cfscript>
requestedDomain = cgi.server_name;
isSecure = cgi.server_port_secure;
</cfscript>
<!--- Content --->
<cfoutput>
The requested domain was #requestedDomain#.<br />
Was the current request secure (0 = No/1 = Yes) ? #isSecure# <br />
</cfoutput>

The following screenshot shows us that this request was not secure:

 

Let's get interactive


Now we are going to get into round trip interaction with web pages. This is where beginners will start to see why we call these web pages "Dynamic Web Pages."

URL variables

We will now be learning a new structure called "URL". This is one way we can pass information from the user back to the server. In our case, we will start by calling the same page via the URL to understand this functionality. We will run the same code twice. The first time, we will not pass in any URL variables:

<!--- Example: 1_9.cfm --->
<!--- Processing --->
<!--- Content --->
<cfdump var="#url#">

The output is as follows:

Our first example, using the URL mentioned below, without the question mark and values to the right of it, returns an empty structure as you can see in the previous screenshot. For the second run, if you look in the address bar you will see that we passed in a URL variable called name with the value John. You can actually pass in many URL variables at the same time, and you often will. This structure works the same way as the CGI structure. We need to add ?name=John to the end of the URL address to get the structure. Here is our new URL: http://localhost/cfb/chapter_1/1_9.cfm?name=John.

It contains no nested structure, so you could output the variable for name in content as follows.

<cfoutput>
  My name is #url.name#.
</cfoutput>

Exception handling

Now we are in some more dangerous territory. Many of the failed web pages come from when we start getting interactive. So in addition to looking at using URL variables, we will take a brief look at how to catch missing variables. This is called exception handling in the programming world. It is pretty universal to use what we call the try-catch method. I will show it to you in script and in tag usage. This will also be an opportunity for you to start understanding error/exception pages that you will get to know as you build your ColdFusion applications and things don't go as planned.

<!--- Example: 1_10.cfm --->
<!--- Processing --->
<!--- Content --->
<cfoutput>
  My name is #url.name#.<br />
</cfoutput>

We will start by running the page correctly. In the URL bar, type in the address followed by ?name=John or any name you like for that matter. Just make sure you type the rest exactly, along with the question mark. This is what you should see with the URL http://localhost/cfb/chapter_1/1_10.cfm?name=John.

Now we will intentionally generate our first error. Remove the question mark from the end of the browser address box and everything that follows it. Now, refresh the page.

Standard error exception

The error message looks like the following:

Many times, you will get detailed information when there is an error. The message clearly states that the name variable is not defined in the URL scope. Not only did it tell us what the error is, but if we scroll down we can see that the page also shows us the line of code where the error occurred.

<CFTRY> and <CFCATCH>

Don't count on this happening all the time. Learning to use try-catch will help narrow down some of these issues. When the page error does not make sense, this may be the best way to figure it out. Look at the next version of code and you will see how try-catch can be used on the page to manage and help fix these errors. It is broadly considered good practice to catch and handle possible issues like this. If an issue occurs, try-catch is the way ColdFusion allows handling many predictable and some less predictable issues.

<!--- Example: 1_11.cfm --->
<!--- Processing --->
<!--- Content --->
<cftry>

  <cfoutput>
    My name is #url.name#.<br />
  </cfoutput>

  <cfcatch>
    <cfdump var="#cfcatch#">
  </cfcatch>
</cftry>

The following screenshot shows us the power of try-catch in code development:

Here, the information is presented differently, but it gives the developer more detail. The exception is placed on the page using <cfdump>. More often than not, you will find that this is the more useful approach to debugging. You can also e-mail the contents of the catch structure to an administrator. You may also note that the StackTrace and objectType structure elements are collapsed. You toggle elements in CFDump by clicking on the element text. This will hide all the nested information until you desire to see it again.

You might wonder why we have included exception/error handing with CFDump. It is because the results of a catch are stored in a variable called cfcatch that contains a pretty nice structure collection. Inside the structure, you will find a nested structure called TagContext. Let us modify our code in such a way that one subset of the structure is dumped to the screen. Change the cfdump as shown in your code:

    <cfdump var="#cfcatch.TagContext#">

The structure allows us to drill down to just the pieces of information we are interested in without pulling the rest of the details along! We see that this information is stored in an array. We haven't covered arrays yet, but you could drill down all the way to the page where the problem occurred. We will learn how arrays work in ColdFusion later in this chapter. But now let's change the line of code one more time and give it a try:

<cfdump var="#cfcatch.TagContext[1].template#">

This is just for illustration, and not how we suggest you practice website development. The following screenshot will show you that we were able to narrow down the results for a more targeted piece of the information when desired:

You will notice something has changed. Where did the fancy wrapper for our CFDump go? It is gone because we are now outputting a simple variable. If there is no structure or complex variable, then we get just the simple variable where the CFDump is located on the page. Because the code error occurred at the end of the line, in this case it will start right from there and this explains why it is on the same line as the web page content in the browser.

 

Setting page defaults


The information you will learn here can be applied to more than page defaults. This is likely the most common place you should use it. We are going to make one minor change in the code that we were using in order to make a new page. We will use the <cfparam> tag to set the default values as shown in the following code:

<!--- Example: 1_12.cfm --->
<!--- Processing --->
<cfparam name="url.name" default="( unknown user )">
<!--- Content --->
<cftry>

  <cfoutput>
    My name is #url.name#.<br />
  </cfoutput>

  <cfcatch>
    <cfdump var="#cfcatch#">
  </cfcatch>
</cftry>

Here we see that the default value is displayed in the browser:

Now, we have learned how to catch and handle exceptions. We have also learned how to prevent this type of error in ColdFusion. In the previous code, we created a default value for the URL structure variable to prevent an error condition and handle it as a predictable exception. If we add the name back to the URL as shown below it still works as expected:

HTML links

We have one more thing that we need to do in order to understand URL structure. We need to add some standard HTML links on the page and then click on them to see what happens. We will be creating two styles of links.

The first link we will be creating is a static link. This link will point back to our dynamic page to show us the one form of interaction through URL variables:

<!--- Example: 1_13.cfm --->
<!--- Processing --->
<cfparam name="url.name" default="( unknown user )">
<!--- Content --->
<cftry>

  <cfoutput>
    My name is #url.name#.<br />

    <a href="?name=Ted">Show this page with Ted for the name.</a><br />
    <a href="?name=Fred">Show this page with Fred for the name.</a><br />
  </cfoutput>

  <cfcatch>
    <cfdump var="#cfcatch#">
  </cfcatch>
</cftry>

This page contains two hyperlinks to pass url variables back to the sever:

Click on either link and you will see the variable that is stored in the link that is passed through to the page when it loads next time from the server. You will also note that the address bar will show the variables passed in via URL requests that reload pages. We will click on Fred to try it out:

It should be apparent that URL variables can come from more than one location. We have seen them originate in the address bar and now in web page links.

Tip

Live applications should have information coming in validated to prevent hackers from messing with data and to make sure data is complete.

Our last use of URL variables for now will be for doing some processing that actually changes based on the links we click on. Enter the following code and give it a try:

<!--- Example: 1_14.cfm --->
<!--- Processing --->
<cfparam name="url.counter" default="10">
<cfparam name="url.calculate" default="0">

<cfset url.counter +=  url.calculate>

<!--- Content --->
<cfoutput>
  I have #url.counter# cars.<br />

  <a href="?calculate=1&counter=#url.counter#">Add One.</a><br />
  <a href="?calculate=-1&counter=#url.counter#">Subtract One.</a><br />
</cfoutput>

Here we see links that pass both the calculation value and the current calculation value:

You can click on add and subtract as many times as you wish. The point is this page has just become very interactive. The counter is passed back through the link we click onto the server from the web page. Notice, as we have told you, that when using the variables to create content, we must wrap them inside a <cfoutput> tag pair and surround the variables with (#) pound symbols.

This will be our last version of the script. It will be a bit fancier than the other scripts we have written. We are going to create a custom structure and see how to interact with that structure using what we have learned so far in this chapter:

<!--- Example: 1_15.cfm --->
<!--- Processing --->
<cfparam name="url.speed" default="10">
<cfparam name="url.acceleration" default="0">

<cfscript>
  myCar = structNew();
  myCar.color = "blue";
  myCar.speed = url.speed + url.acceleration;
</cfscript>

<!--- Content --->
<cfoutput>
  <a href="?acceleration=-1&speed=#myCar.speed#">Slower</a>&nbsp;
  <a href="?speed=#myCar.speed#">Cruise</a>&nbsp;
  <a href="?acceleration=1&speed=#myCar.speed#">Faster</a><br />

  <cfdump var="#myCar#" label="My Car">
</cfoutput>

This browser window lets us see the results of the car structure variables as we click to modify our current speed:

We have learned that creating a new structure is done by assigning a value to the variable using the function structNew(). You can nest structures inside of structures in addition to actual variable storage containers. It's the first step towards packaging your data inside your application. As applications grow, you will not want everything with simple variables setting at the root level of your variable structure. That would be impossible to maintain.

Another note is that we have persisted the values of the speed of the car by passing through the URL variables. We will learn additional ways of making our values last from one page call to the next. We learned the basics concepts of the structure and gained an understanding of URL variables.

 

Introduction to lists and loops


Lists are stored inside string variables. You can also have a list variable stored inside a structure. Lists have a "separator" which is also known as a delimiter to divide the items so the server can evaluate the items. We are going to go back to our FAQ application concept and build on what we have learned. Let's look at the code for lists:

<!--- Example: 1_16.cfm --->
<!--- Processing --->
<cfparam name="url.speed" default="10">
<cfparam name="url.acceleration" default="0">

<cfscript>
  questions = "What is the speed limit?,What is a car?,How much is gas?";
</cfscript>

<!--- Content --->
<cfoutput>
  The second question is:<br />&nbsp;&nbsp;&nbsp; 
  #listGetAt(questions,2)#
</cfoutput>

The browser window now shows us the second question:

You can see that the list has three items in it. We have the content request the second item for display. The listGetAt() function is another one of those simple, powerful functions that makes ColdFusion so easy to program. You will find a number of wonderful list functions built into the language. We are going to mix lists and loops so you can see how things work together:

<!--- Example: 1_17.cfm --->
<!--- Processing --->
<cfparam name="url.question" default="What is the speed limit?">

<cfscript>
  questions = "What is the speed limit?,What is a car?,How much is gas?";
  answers = "55,Depends who you ask!,more than before";
  myQuestion = listContains(questions,url.question);listContains(questions,url.question);
</cfscript>

<!--- Content --->
<cfoutput>
  <strong>#listGetAt(questions,myQuestion)#</strong><br />
  Answer:&nbsp; #listGetAt(answers,myQuestion)#<br /><br />
</cfoutput>

All Questions
<hr />
<cfloop list="#questions#" index="iQuestion">
  <cfoutput>
    <strong>Q</strong>: <a href="?question=#iQuestion#">#iQuestion#</a><br />
  </cfoutput>
</cfloop>

Our browser now shows us the power of looping in action:

We made two lists this time, one list for questions called, of course, "questions" and another for answers called "answers". When you build pairs of lists like this, check twice that they have the same number of items in each list to prevent errors. This will keep us out of the debugging phase of development. If you look where we assigned the numeric value of myQuestion, you will see that we are able to match the question asked to the list. If there is an exact match, then the number of that item in the list is returned. You should also note that in the CFLoop list, the index variable contains the actual item stored in that position in the list.

Click on different questions and see how things work. You will be able to see the variables being passed in the address bar.

Note

ListContains() will work to find exact matches in a list. If you just want to find the first item in a list with a partial match, then use ListFind(). Both of these also have a NoCase version available.

We will continue to provide more information on loops as we get into arrays in the next segment! There are several types of loops and this is one of the more popular commands among ColdFusion developers.

You are coming along great and have nearly finished your first chapter. You may not realize it yet, but by now you have started to learn to think in ColdFusion. Don't expect to be a master or even understand the fine points of applying your knowledge. That knowledge will come with the chapters that follow. Right now, we are just building a foundation.

 

Understanding arrays


The array is an interesting variable construct. You can think of an array as a collection of commonly named variables with a numeric index. We will take the last code example and transfer it to arrays. Here we will change the backend in major ways, but the frontend will run completely the same from a user's point of view. If you look closer, you will be able to see that we are now passing a variable from page to page rather than the whole questions as before. Let's check out the code:

<!--- Example: 1_18.cfm --->
<!--- Processing --->
<cfparam name="url.question" default="1">

<cfscript>
  question = arrayNew(1);
  question[1] = "What is the speed limit?";
  question[2] = "What is a car?";
  question[3] = "How much is gas?";
  answer = arrayNew(1);
  answer[1] = "55";
  answer[2] = "Depends who you ask!";
  answer[3] = "more than before";
</cfscript>

<!--- Content --->
<cfoutput>
  <strong>#question[url.question]#</strong><br />
  Answer:&nbsp; #answer[url.question]#<br /><br />
</cfoutput>

All Questions
<hr />
<cfloop from="1" to="#arrayLen(question)#" index="iQuestion">
  <cfoutput>
    <strong>Q</strong>: <a href="?question=#iQuestion#">#question[iQuestion]#</a><br />
  </cfoutput>
</cfloop>

Rather than two lists at the top, we now have two array variable constructs. Before you start assigning variables to an array, you need to declare the variable as an array type. Arrays can be multi-dimensional. The truth is this is very rarely done, but you may find some use case now and then. We will focus on a single-dimensional array. If you forget to pass in the number of dimensions when you declare an array, you will get an error when that code runs. So, do remember to declare the number of dimensions.

Note

The maximum number of dimensions in ColdFusion is three. Remember that a large array in multi dimensions can consume huge amounts of computer memory. Think twice before using multi-dimensional arrays for this reason.

You will find a rich collection of array functions built into ColdFusion. You can use arrayDeleteAt() to remove an item in the middle of an array. There is also an arrayInsertAt() which does the opposite. There are three things that you need to keep in mind when using arrays:

  • Don't remove items in the middle of an array list without using the built-in functions. This could create a missing element and create an error when looping through the array collection.

  • Don't count on an item staying in the same indexed position. It may seem odd that we call the position an index and think the item can move. This is different because unlike the index in a book, arrays are dynamic.

  • The number of items in an array can change. It is best to use the arrayLen() function as we did in the example code in order to know the current length of an array.

Now we will perform a minor rewrite and run the same code as a multi-dimensional array. This is also called an array of structures. Each dimension of the array has structure. This allows for some unique layout of data within your application memory. We will add a CFDump at the end of the code, so the structure created can be presented for view:

<!--- Example: 1_19.cfm --->
<!--- Processing --->
<cfparam name="url.faq" default="1">

<cfscript>
  faq = arrayNew(1);
  faq[1] = structNew();
  faq[1].question = "What is the speed limit?";
  faq[1].answer = "55";	
  faq[2] = structNew();
  faq[2].question = "What is a car?";
  faq[2].answer = "Depends who you ask!";
  faq[3] = structNew();
  faq[3].question = "How much is gas?";
  faq[3].answer = "more than before";
</cfscript>

<!--- Content --->
<cfoutput>
  <strong>#faq[url.faq].question#</strong><br />
  Answer:&nbsp; #faq[url.faq].answer#<br /><br />
</cfoutput>

All Questions
<hr />
<cfloop from="1" to="#arrayLen(faq)#" index="iFAQ">
  <cfoutput>
    <strong>Q</strong>: <a href="?faq=#iFAQ#">#faq[iFAQ].question#</a><br />
  </cfoutput>
</cfloop>
<cfdump var="#faq#">

Now we have the same basic information but this time our browser window shows the array of structures feeding the output:

We have only touched the surface of what you can do with structures, arrays, and loops. The masters of ColdFusion are still finding creative uses for them. They are pretty simple to master and very flexible to implement.

 

Conditional processing with If/<cfif>


Now, we have reached the last segment of our fast track introduction to ColdFusion. We would be amiss if we were to forget conditional processing. There are two tags which make up the bulk of conditional processing in ColdFusion.

The first tag is <cfIf>. The second is <cfelse> which has a variation called <cfelseif> where the functionality of the two is combined. If you are familiar with any other language, writing code in ColdFusion should be very similar. The only out of the ordinary issue is that when coding with tags, the language needs to be able to tell the difference between tag braces and greater and less than logic. In ColdFusion tag requests, this is done by replacing the greater than symbol with GT. We replace the less than symbol with LT. We use GTE and LTE for greater than or equal to and less than or equal to, respectively. If something is equal we can use either IS or EQ.

Now that we have covered these concepts, let's get to something fun. Let's look at some code! What can we do to make sure someone doesn't fool around with the URL and make our page fail by changing URL variables? Let's put some conditional processing in to perform business logic in the processing section of our pages:

<!--- Example: 1_20.cfm --->
<!--- Processing --->
<cfparam name="url.faq" default="1">

<cfscript>
faq = arrayNew(1);
  faq[1] = structNew();
  faq[1].question = "What is the speed limit?";
  faq[1].answer = "55";	
  faq[2] = structNew();
  faq[2].question = "What is a car?";
  faq[2].answer = "Depends who you ask!";
  faq[3] = structNew();
  faq[3].question = "How much is gas?";
  faq[3].answer = "more than before";
</cfscript>

<cfif NOT isNumeric(url.faq)>
  <cfset url.faq = 1>
<cfelse>
  <cfset url.faq = round(url.faq)>
  <cfif url.faq LT 1>
    <cfset url.faq = 1>
  <cfelseif url.faq GT arrayLen(faq)>
    <cfset url.faq = arrayLen(faq)>
  </cfif>
</cfif>

<!--- Content --->
<cfoutput>
  <strong>#faq[url.faq].question#</strong><br />
  Answer:&nbsp; #faq[url.faq].answer#<br /><br />
</cfoutput>

All Questions
<hr />
<cfloop from="1" to="#arrayLen(faq)#" index="iFAQ">
  <cfoutput>
    <strong>Q</strong>: <a href="?faq=#iFAQ#">#faq[iFAQ].question#</a><br />
  </cfoutput>
</cfloop>

We will skip the screenshot because there is no change to how the user sees the page. What is different is only some processing logic to prevent someone from messing with the stability of the page. While the stability of someone hacking a FAQ isn't a big deal, this will lay the foundation for protecting things such as e-commerce pages as your skills grow.

Oh, perhaps earlier you were thinking that we forgot the Boolean variable type. The conditional statements inside of these if statements actually evaluate to either true of false. These are the Boolean values. You will also find that you can use either a zero or nonzero number to represent a Boolean logical evaluation. Therefore, any number that evaluates to either zero or false has the same result. The other nonzero numbers and true, yes, and no are also matched Boolean conditions. You could just take the same code and assign it to a variable. Then, you could use the variable inside the if statement instead of evaluating the logic inside of the statement. Normally, just put it inside of the <cfIf> statement and you will do well:

<cfset myBoolean = NOT isNumeric(url.faq)>

First we check to make sure that the variable is in fact a number. I suggest you change the value in the address bar to text just to see that this doesn't break the page. You will find that it chooses to show the first item because the input in the URL variable is now invalid. This is done using the NOT logical condition. The NOT takes the result of the test and reverses it. You will also notice that if this is not the condition, then an alternate set of code is processed.

<cfif NOT isNumeric(url.faq)>

Next we will attempt to break it by entering in a negative number. As there are no items at that location in the array index, it would normally have broken the page. We have prevented that with our conditional logic by again resetting the value when any basic type of hack occurs.

Let's take one more look at the code with all the processing logic inside CFScript. If you use another platform and like script more, this may be your style. If it is not your style there is no problem. The beauty of the platform is that it is flexible. You can do it both ways.

<!--- Example: 1_21.cfm --->
<!--- Processing --->
<cfparam name="url.faq" default="1">

<cfscript>
  faq = arrayNew(1);
  faq[1] = structNew();
  faq[1].question = "What is the speed limit?";
  faq[1].answer = "55";	
  faq[2] = structNew();
  faq[2].question = "What is a car?";
  faq[2].answer = "Depends who you ask!";
  faq[3] = structNew();
  faq[3].question = "How much is gas?";
  faq[3].answer = "more than before";

if(! isNumeric(url.faq)){
  url.faq = 1;
} else {
  url.faq = round(url.faq);
  if(url.faq < 1){
    url.faq = 1;
  } else if(url.faq > arrayLen(faq)){
    url.faq = arrayLen(faq);
  }
}
</cfscript>
<!--- Content --->
<cfoutput>
  <strong>#faq[url.faq].question#</strong><br />
  Answer:&nbsp; #faq[url.faq].answer#<br /><br />
</cfoutput>

All Questions
<hr />
<cfloop from="1" to="#arrayLen(faq)#" index="iFAQ">
  <cfoutput>
    <strong>Q</strong>: <a href="?faq=#iFAQ#">#faq[iFAQ].question#</a><br />
  </cfoutput>
</cfloop>

We only show the top half of the code here because the content section of the code is identical to the previous example. You may note that you can use some more traditional script-style logic symbols when coding in script. With both of these in the book, it should help anyone to evaluate between syntax for either script or tag-based logic.

 

Conditional processing with switch


You can achieve contextual selection of code segments with <cfIf>. However, the <cfSwitch> tag has unique style that will become a conditional processing favorite in certain scenarios. As our goal is language mastery, in this chapter we will again restructure the FAQ example using the switch statement logic. This is by no means the best use of a switch statement, but it will help you see how the logic works. You will not see any difference when you look at the browser from the user side.

<!--- Example: 1_22.cfm --->
<!--- Processing --->
<cfparam name="url.faq" default="">

<cfscript>
  faq = arrayNew(1);
  faq[1] = structNew();
  faq[1].question = "What is the speed limit?";
  faq[1].answer = "55";	
  faq[1].id = "a";
  faq[2] = structNew();
  faq[2].question = "What is a car?";
  faq[2].answer = "Depends who you ask!";
  faq[2].id = "b";
  faq[3] = structNew();
  faq[3].question = "How much is gas?";
  faq[3].answer = "more than before";
  faq[3].id = "c";
</cfscript>
<cfswitch expression="#url.faq#">
  <cfcase value="b">
    <cfset question = faq[2].question>
    <cfset answer = faq[2].answer>
  </cfcase>
  <cfcase value="c">
    <cfset question = faq[3].question>
    <cfset answer = faq[3].answer>
  </cfcase>
  <cfdefaultcase>
    <cfset question = faq[1].question>
    <cfset answer = faq[1].answer>
  </cfdefaultcase>
</cfswitch>

<!--- Content --->
<cfoutput>
  <strong>#question#</strong><br />
  Answer:&nbsp; #answer#<br /><br />
</cfoutput>

All Questions
<hr />
<cfloop from="1" to="#arrayLen(faq)#" index="iFAQ">
  <cfoutput>
    <strong>Q</strong>: <a href="?faq=#faq[iFAQ].id#">#faq[iFAQ].question#</a><br />
  </cfoutput>
</cfloop>

We added an extra structure element to each array item just to make this example do a better job at illustrating the switch condition. You will note that the hyperlink reference passed to the browser is now based on the value of the ID in each structure element. If url.faq contains no value, then the default value will be empty. This is because we are showing how to use the cfdefaultcase when there is no other match. One of the beauties of this is we were able to eliminate all the protection logic we had in the previous example. In some ways, the page has been made simpler in this example.

When the page comes to the cfswitch statement, the value of the expression is stored for comparison with each case until a match is found. If no match is found, it will check for a default case code segment. If the default case exists, then that code segment will be executed accordingly. Try it out and see if you understand what we have accomplished with this code. You might at this point even add a couple of new questions just to get a feel of what you have learned.

ColdFusion 9 added another case statement to the switch condition. This would be <cffinally>.

 

Summary


Now we will have a look at what we have learned in our first chapter on dynamic web development:

  • The difference between static HTML pages and dynamic ColdFusion pages

  • Simple variables (string or text, numeric, and Boolean)

  • Structured variables such as URL and CGI

  • Setting default variable values for pages

  • Simple techniques to assist in debugging code

  • Basic use of try-catch exception handling

  • Use of lists stored in simple string variables

  • Understanding variable collections (arrays and structures)

  • Use of loops with the help of lists, arrays, and structures

  • Introduction to conditional logic (if and switch)

  • Tags/functions

About the Author

  • John Farrar

    John Farrar is a man who has a passion for pragmatic technology. He started working on computers in the late 70s and has watched the trends as closely as he watches the milestones. His work included programming on early computers, repairing military flight simulators in the navy, and working on web technology that helps people get business done. This work included building early commerce solutions for Apple, Brunswick Recreation, and Casio and working for a number of other companies along the letters of the alphabet. He is inspired and passionate about understanding the need before choosing the technology that answers the challenge.

    Over the years, John has worked on a couple of books for ColdFusion, multiple open source projects from early Fusebox, community participation with jQuery, and some frameworks he created on his own. He has spoken at about a dozen conferences over the years and worked on supporting local and online users as time has permitted. He has provided technical training from online courses, in person class instructions, and a number of great intern programmers that let him share their entrance into the world of writing software.

    Browse publications by this author

Latest Reviews

(2 reviews total)
Quick and easy access to quality content
I mainly purchased this book to use as a resource, as needed. Although I haven't used it extensively yet, it has already provided benefit for what I have needed so far.
Book Title
Unlock this full book FREE 10 day trial
Start Free Trial