Chapter 18. Using ColdFusion Markup Language (CFML)

In this chapter

Introducing CFML

When ColdFusion was introduced in the last chapter, I mentioned that one of the elements was the ColdFusion Markup Language, frequently referred to as CFML. CFML is a tag-based programming language, very similar to HTML in that the functionality that the ColdFusion server is expected to perform is indicated by a start tag like <CFOUTPUT> and an end tag like </CFOUTPUT>. Anything inside those tags is processed by the ColdFusion engine and everything else is left up to the web server application. This means that in the following snippet of code

<B><CFOUTPUT>Hello World!</CFOUTPUT><B>

the ColdFusion engine would output the text Hello World! and the web server would bold the text. This might seem a little silly at this point because the web server could just as easily handle the output of the text, but as you’ll see later in the chapter, the power of ColdFusion goes way beyond creating simple text.

Note

You’ll notice throughout this book that when I refer to tags, I type them in all caps. This is not a requirement because ColdFusion is not case sensitive (for example, <cfoutput> is the same as <CFOUTPUT>), but is merely a coding style that I use. By doing this, I am able to easily distinguish my CF tags from other non-ColdFusion text.

Tip

If you’re not into writing your own code, don’t worry. Dreamweaver is an excellent development tool for the ColdFusion platform and it writes the code for you.

Understanding the Language

The CFML language consists of about 100 tags, each enclosed in angle brackets like HTML tags, and all the CFML tag names start with CF. Each of these tags indicates what function the ColdFusion server should perform on the content that falls between the tags.

ColdFusion also contains quite a few functions that enable you to perform operational comparisons, check for certain conditions, and even perform simple file-based operations. These functions are also invoked by a set of tags and many of them are capable of accepting arguments.

Table 18.1 lists some commonly used ColdFusion tags and functions, and later in the chapter we’ll take a look at how they operate.

Table 18.1. Some Commonly Used ColdFusion Tags

Tag

Purpose

CFAPPLICATION

Defines various client behaviors associated with an application, such as whether the client can log information in a cookie, and whether the client session will time out.

CFARGUMENT

Within a function, defines a parameter (data passed to the function).

CFBREAK

See CFLOOP.

CFCALENDAR

New in ColdFusion MX 7, this tag allows you to invoke interactive Flash-based calendars.

CFCATCH

See CFTRY.

CFCOMPONENT

Creates a ColdFusion component (CFC), an object encapsulating procedures (functions, referred to as methods), and data (variables and parameters).

CFDIRECTORY

Returns a list of files in a directory. Can also create, delete, and rename directories.

CFDOCUMENT

New in ColdFusion MX 7, this tag creates a PDF or FlashPaper output of the content that falls between the tags.

CFDUMP

Displays the contents of variables, objects, components, user-defined functions, and other elements. Useful for debugging.

CFELSE

See CFIF.

CFFILE

Performs operations such as reading, writing, and appending to files on the ColdFusion server.

CFFORM

Creates an instance of a form that can be validated on the server side.

CFFORMITEM

New for ColdFusion MX 7, this tag enables you to create a container that specifies controls for multiple forms.

CFFUNCTION

Defines a ColdFusion function (an object encapsulating a procedure).

CFHTTP

Generates an HTTP request and handles the response from the server.

CFIF

Executes enclosed code if a condition is true. Can be used with CFELSE to define an action to perform if the condition is not true.

CFIMPORT

Imports all ColdFusion pages in a directory into the calling page as a custom tag library.

CFINCLUDE

Adds the contents of the included ColdFusion page to the page containing the CFINCLUDE tag, as if the code on the included page were part of the page containing the CFINCLUDE tag.

CFINVOKE

Invokes (runs or executes) either a function (method) in a component or a web service.

CFLOCK

Locks (prevents simultaneous access to) a single section of code, two or more different sections of code, or a scope. Locks prevent simultaneous change of the same variable to two different values.

CFLOOP

Loops through the tag body zero or more times, based on a condition specified by the tag attributes. The CFBREAK tag exits a CFLOOP tag.

CFMAIL

Sends SMTP mail messages with application variables, query results, or server files. (See also CFPOP, for getting mail.)

CFMODULE

Invokes a custom tag, providing a workaround for custom tag name conflicts.

CFNTAUTHENTICATE

New for ColdFusion MX 7, this tag enables you to authenticate user credentials against a Windows NT domain.

CFOBJECT

Loads an object into a variable. Can load a CFC or an object written in other programming languages, including COM (Component Object Model) components, Java objects such as Enterprise JavaBeans, or CORBA (Common Object Request Broker Architecture) objects.

CFOUTPUT

Displays output that can contain the results of processing ColdFusion functions, variables, and expressions.

CFPARAM

Creates a variable if it doesn’t already exist. Optionally, sets the variable to a default value. If the variable already exists, CFPARAM does not change its value.

CFPOP

Retrieves and/or deletes email messages from a POP mail server.

CFQUERY

Establishes a connection to a database (if a connection does not exist), executes a query operation such as insert, retrieve, update, or delete, and returns results.

CFRETURN

Returns a result from a function.

CFSET

Sets or resets the value of a ColdFusion variable. If the variable doesn’t already exist, CFSET creates the variable and sets the value. If the variable does exist, CFSET sets the value.

CFTIMER

New in ColdFusion MX 7, this function displays a timer indicating how long it took a section of CFML code to execute.

CFTRY

Used with one or more CFCATCH tags to catch and process exceptions (events such as failed database operations that disrupt normal program flow).

Many of ColdFusion’s functions are able to accept arguments that further refine how the function behaves. When learning the tags, pay close attention to what types of data the functions can accept.

In addition to tags and functions, ColdFusion enables you to create variables. Think of a variable as a data container that contains a unique name. Using CFML, you can not only name the container, but fill it with data as well. For instance, take a look at the following code:

<CFSET myName = "Sean">

This code defines a variable called "myName". It also specifies that the initial value of the variable is Sean. Because the data being inserted into the variable is surrounded by quotes, ColdFusion recognizes it as a string—or data that can contain both numeric and alphanumeric data. After the variable is established, you can display it by using the cfoutput tag like this:

<CFOUTPUT>#myName#</CFOUTPUT>

Note

When calling variables, surround the variable name with pound signs so that the ColdFusion engine knows that it shouldn’t simply output the text between the tags.

Tip

When creating variables in ColdFusion, remember these tips:

  • Variable names must begin with a letter, underscore, or Unicode currency symbol.

    You cannot begin variable names with a number.

  • Variable names cannot contain spaces.

  • Variable names are not case sensitive.

Now that you’ve created your variable, you aren’t limited to simply displaying the variable. Depending on the type of data stored in the variable, you can use it in calculations or even run comparisons against it.

When you create your variable, you also need to consider its scope. The scope of a variable defines how long the variable should exist and what portions of the page code can use the variable. Because it’s important to know when it’s okay to use your variable, it’s important to define the scope of each variable. ColdFusion has a variety of predefined scope types, so the easiest way to define the scope of a new variable is simply to assign it to one of these types.

You can specify a scope explicitly by putting it before the variable and separating the two with a period. For instance, if you wanted to define the myName variable scope as "session" so that it lasted for the duration of the user’s browser session, you would define it by typing

<CFSET Session.myName = "Sean">

This would define the variable, set the initial value, and define the scope of the variable as existing until the session expires.

Table 18.2 lists some commonly used variable types that are available in CFML.

Table 18.2. Commonly Used Variable Types Available in CFML

Data Type

Data Stored

String

Text data wrapped in quotes such as "Hello World" or "Sean".

Number

Numeric values. Unlike other languages, CFML does not require that you specify whether or not the number contains decimal points.

Boolean Value

“Yes”, “No”, “True”, “False”, 0, or 1.

Date/Time

Date and time values in formats such as 08/05/2005, 2005-08-05, or 08/05/2005 02:30:00 pm.

Custom Tags

In the previous section, you saw how simple it was to call some of the built-in tags such as the CFOUTPUT and CFSET tags. Because the behaviors of these tags are predefined, adding a built-in CFML tag to your code is as easy as adding a standard HTML tag. One of the greatest features of ColdFusion, however, is its extensibility. This means that you can extend CFML beyond the capabilities of the built-in tags by creating your own custom tags, which work just like standard CFML tags. This means that you can create your own tags that contain functionality that can be reused over and over in any ColdFusion pages.

If you’re not up to authoring your own custom tags yet, literally thousands of custom tags are available through the ColdFusion Exchange at www.macromedia.com, many of them freeware or shareware. Before you go and spend a lot of time creating a custom tag, it’s usually a good idea to browse the Exchange to see whether someone else has already done the work for you. No need to reinvent the wheel!

Custom Tag Basics

When you create a custom CFML tag, it is stored in its own separate file. Although there are several ways of invoking a custom tag, the easiest is simply to use a tag with the name of the file, with cf_ in front of it. For example, if the custom tag is contained in a file named lastmodified.cfm, you would invoke the custom tag by typing cf_lastmodified.cfm. You can also invoke a custom tag with the cfmodule and cfimport functions. They are often favored for managing a large number of custom tags because they are capable of handling any custom tag name conflicts that might arise.

Note

There are two kinds of custom tags: CFML and CFX. CFX tags are written in C++ or Java. Only CFML tags are covered in this book.

ColdFusion looks for custom tags first in the same directory as the calling page, then in the CFusionMXCustomTags directory, then in subdirectories of the CFusionMXCustomTags directory, and finally in directories that you can specify in the ColdFusion MX Administrator.

Creating a Custom Tag

Creating your own custom tag might sound like a daunting task, but keep in mind that custom tags usually consist of code that you might be writing over and over again (hence the need for a custom tag). So if you’re going to build the same code block over and over, you might as well create a custom tag instead and save yourself some time.

The first step in creating a custom tag is to determine what it is you want to accomplish. For instance, suppose you wanted every page to display a “last updated on” text block that also included the date when the page was last updated. You could open a text editor and build the following code block:

<CFPARAM name="attributes.lastmodified" default="">
<CFOUTPUT>
<I>This page was last updated on #attributes.lastmodified#</I>
</CFOUTPUT>

Essentially, this code block takes a date that is passed by the calling page and displays the code block and the date. To invoke the custom tag, you would call it in a CFML page by using code similar to the following:

<HTML>
<HEAD>
<TITLE>My Page</TITLE>
</HEAD>
<BODY>
Type your content here.
<CFLastModified LastModified="June 6, 2005">
</BODY>
</HTML>

This page now passes the date on which the page was last modified and it is then displayed, along with the text block, on the page. Although this example may seem a bit remedial, it does demonstrate that each custom tag requires two fundamental things:

  • The defined custom tag code

  • A page that calls that tag and passes any parameters to it.

Truly, the best way to fully understand how custom tags work is to build a few remedial tags yourself, and then spend time on the Macromedia Exchange downloading, reviewing, and looking at the code involved in each of the custom tags on the Exchange.

Using ColdFusion for Database Operations

Although defining and displaying custom variables might enhance the functionality of your website, the more powerful tool that ColdFusion offers is the capability to communicate with databases and display and interact with content stored within them.

Imagine if your client, Retro’s Cycles, had 100 motorcycles in inventory for sale. It wouldn’t be reasonable to consider creating an individual web page for each of the 100 motorcycles. It would, however, be a better idea to store the information about the motorcycles in a database and then create a small set of pages that interacts with the database to display information about what is in inventory. Imagine being able to build a search page, a results page, and a details page that enable you to display the content details for each of the 100 motorcycles. That’s 3 pages that now have taken the place of 102 pages. Talk about a timesaver!

ColdFusion is able to interact with a database in several different ways. It can retrieve data, update data currently stored in the database, insert new data, or delete existing data.

Retrieving Data

The most common database interaction is simply drawing data out of the database for display on a page. To do this, however, you need to have established a connection to the database and then create a recordset. Think of a recordset as a container that holds all the database records that you have requested. For instance, if you asked the database to retrieve all records where the Make field is equal to "Honda", the recordset would contain only the records for Honda bikes.

To request this data, you need to combine the <CFQUERY> tag with a SQL query that contains the proper syntax for returning the correct records. The <CFQUERY> tag specifies the database from which to retrieve data. The SELECT statement specifies the table(s) within the database, and which records in the tables to get.

The simplest SELECT statement looks like this:

SELECT * FROM Inventory

This statement says, “Retrieve all columns (fields) of all rows (records) from the Inventory table.” The asterisk is a wildcard meaning “all columns.” All rows are retrieved, because the statement contains no limiting clause for selecting only a subset of rows. In this case, each row is a different product, and the columns are the attributes of the product, such as the item’s unique ID, make, model, year, list price, and so on.

If you want to limit the records your recordset contains, you can use a WHERE clause to select only specified rows. For instance, the following statement retrieves only records where the Make is equal to "Honda":

SELECT *
FROM Inventory
WHERE Make = 'Honda'

To use this SQL statement in ColdFusion, enclose it in a <CFQUERY> tag. In the following example, the <CFQUERY> tag specifies the retroscycle database, and assigns the name rsHondas to the recordset that is created:

<CFQUERY name="rsHondas" datasource="retroscycles">
SELECT *
FROM Inventory
WHERE Make = 'Honda'
</CFQUERY>

Inserting Records

Adding content to your database is almost as simple as retrieving data. Inserting a record usually requires completion of a form and form fields: You enter the data into the form and have it added after you submit it. The form then passes the data to a page (or code on the same page) that processes a SQL command similar to this:

INSERT INTO Inventory (Year, Make, Model)
VALUES (#FORM.Year#, #FORM.Make#, #FORM.Model#)

Basically, this SQL query takes the contents of the Year, Make, and Model form fields and adds them to the Year, Make, and Model fields in a new record in the database.

Therefore, when you create your full CFML code, it would look something like this:

<CFQUERY name="rsHondas" datasource="retroscycles">
INSERT INTO Inventory (Year, Make, Model)
VALUES (#FORM.Year#, #FORM.Make#, #FORM.Model#)
</CFQUERY>

Updating Records

Another common database interaction is updating a record that already exists in the database. Like the Insert process, this requires two different elements: a form that displays the existing data and allows you to change it, and an action that replaces the existing data with the updated information after the form is submitted.

The form is created with a standard HTML form, or you can use a form created in CMFL by using the <CFFORM> tag. The update action uses the <CFQUERY> tag, along with the SQL update statement that looks something like this:

UPDATE Inventory
SET Make='Kawasaki'
WHERE Make='Honda'

This update statement modifies all records in the database where the Make is currently Honda and changes the Make field to Kawasaki. Although this is a global change to the entire table, you can limit the update to a single record by further refining the WHERE clause to look something like this:

UPDATE Inventory
SET Make='Kawasaki'
WHERE Make='Honda' AND InventoryID = '00011'

This update statement would affect only the record that has an InventoryID of 00011.

Because it’s likely you’ll be making the updates via a form, the form variables that are submitted can also be used in the SQL statement. For example, look at the following:

UPDATE Inventory
SET Make=#FORM.Make#
WHERE Make='Honda' AND InventoryID = #FORM.InventoryID#

This grabs whatever value is stored in the Make form field and enters it into the Make field in the database. Note that this affects only the record that is passed in the InventoryID form field.

Note

Fields present in the database but not in the UPDATE statement remain unchanged.

Deleting Records

Although deleting records is certainly an important part of database maintenance, it is important to remember that deleting permanently and irrevocably removes records from the database. There is no Edit, Undo command, and you can’t restore the data without resorting to a known, good backup such as a tape backup or SQL backup file. So use the command deletion process wisely and cautiously.

When deleting records, the more detail about which record to delete, the better. For instance, consider this simple statement:

DELETE * FROM Inventory

Because it puts no limits on what to delete, it totally wipes out all the records in the Inventory database. Gone...wiped...kaput.

Therefore, it’s a wise idea to restrict your delete commands so that they affect only the record you want. For instance, consider the following command:

DELETE FROM Inventory
WHERE InventoryID = '00001'

If the InventoryID field is a primary key that increments automatically, you can be sure that there will only ever be one record with an InventoryID of 000001. This means that you have deleted only one record and you hope it’s the correct one.

Keep in mind that relationships between tables can cause delete operations to fail. For example, if you had a Sold table that depended on the Inventory table and you tried to execute a DELETE FROM Sold (delete all records in the Sold table), you would receive an error stating The record cannot be deleted or changed because table 'Inventory' includes related records.

Troubleshooting

I tried connecting to my database, but I got an error that connection could not be established. What happened?

There are a couple things you can check. First, ensure that you spelled the data source name correctly in your code. If it is correct, check that the path specified in the ColdFusion Administrator is still the correct path to the database.

I am receiving a syntax error that I just can’t seem to figure out. Where should I look to resolve the issue?

First off, pay close attention to the line number that is being indicated in the error. Look at that line and determine whether you forgot to add an end tag or close a quote or add a pound sign at the beginning or end of your variables. These three things cause a lot of syntax errors and are usually easy to track down after you know what to look for.

Best Practices—Properly Documenting Code

As you begin developing CFML code, I can’t stress to you how important it is to document your code as you go along. Just like HTML, CFML provides special character combinations that indicate when a comment tag begins and when it ends. To start a comment, the <!- combination is used, whereas the --> combination is used to indicate that a comment has ended. For instance, suppose you write a block of code that draws two values from the database and averages them. Something as simple as adding a comment line such as the following

<!--This function draws the number of motorcycles in the database and
the prices of all the motorcycles and creates an average price-->

can save you a lot of time when you have to revisit your code down the road. In addition, if someone else comes along and has to interpret your code, these helpers go a long way in helping them to understand what you were trying to accomplish.

Start developing your documentation skills now and you will reap the benefits of clear, understandable code for the rest of your career.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.122.244