This article is for you if you are a beginning coder. You know how to do marvelous things like query databases and output the results. You can take data submitted from a form, manipulate it, and perform calculations. After mastering these fundamentals, you are ready to expand your knowledge of ColdFusion. This article explains six ColdFusion tags that you can easily start using today.
These tags are beyond the basics, are quick to learn, and provide utility. The tags listed here have a brief explanation of their use, a detailed look at the attributes, and an example of use.
The most important tag in this article is cfqueryparam. Most of you are not using cfqueryparam - I know, because I have worked on your code! If you take one thing away from this article, please take that tag. But in order to understand cfqueryparam, we should first take a look at cfparam. So let's start there.
cfparam
<cfparam name = "param_name" type = "data_type" default = "value">
At the most basic level of cfparam, it determines whether a variable exists. It can also verify that the variable is of the correct type. If neither of these conditions is met the tag will throw an error, or optionally set the variable to a default value. As it sounds, it can be used in a few different ways. These uses correspond with the attributes, so let's start by taking a look at them.
The first attribute is name. This is the name of the variable whose existence you want to determine. It's the only required attribute. If this is the only attribute used, it operates in this way: it checks if a variable of that name exists, and if it doesn't, it throws an error:
<cfparam name="myVariable">
Essentially, it is the equivalent of this code
<cfif NOT isDefined("myVariable")>
<cfthrow />
</cfif>
The second attribute is type. This defines what data type the variable is supposed to be. There are a few options: any, array, binary, boolean, date, guid, numeric, query, string, struct, UUID, variableName. Most of these values are self explanatory, for a more detailed description of these types please see the ColdFusion documentation. If the type attribute is not specified, the default is any. Meaning, the variable has to be a variable of any kind, just as long as it as a variable:
<cfparam name="myBoolean" type="boolean">
Essentially it is the equivalent of this code
<cfif NOT isDefined("myBoolean") AND NOT isBoolean("myBoolean")>
<cfthrow />
</cfif>
The last attribute is default. This attribute defines what value the variable holds, if it does not meet the previous conditions. Looking at our previous code representations, it changes the cfthrow, to a cfset. Instead of throwing an error, it assigns the variable to a default value. In other words, if the variable does not exist or is not of the right type, then the variable is created and set to this default value:
<cfparam name="myBoolean" type="boolean" default="false"/>
Essentially is the equivalent of this code
<cfif NOT isDefined("myBoolean") AND NOT isBoolean("myBoolean")>
<cfset myBoolean = false />
</cfif>
It is good coding practice to cfparam your variables at the beginning of a document. By doing this you are checking for the existence of variables, and if they don't exist you create them. This avoids several isDefined() functions, or worse, missing variable errors. It also lets the coder know what variables will be coming into the page - that is, if you aren't documenting your code.
You have probably realized that simply checking for a variable's existence doesn't guarantee that there is valuable information stored in it. By using cfparam you are ensuring the variable exists and is the right type. Now you are left with only the task of performing operations to determine the quality of the information. Which is a lot simpler.
Example of use:
You have a page that pulls a list of users from a database. You pass the order in the url (ascending or descending). At the top of the processing page you put:
<cfparam name="url.order" type="string" default="ASC">
This code looks for order in the url, if it doesn't exist or isn't a string, it creates it with the value of "ASC".
cfqueryparam
<cfqueryparam value = "parameter value" CFSQLType = "parameter type" maxLength = "maximum parameter length" scale = "number of decimal places" null = "Yes" or "No" list = "Yes" or "No" separator = "separator character">
Cfqueryparam is a lot like cfparam in that it validates the incoming value, but it's more robust and also offers binding. We'll tackle these one at a time. As the name implies, it's part of a query. Think of it as this: as cfparam is to cfm files, cfqueryparam is to query. There is one essential difference however: cfqueryparam has no default value.
So you might ask yourself, why do you need cfqueryparam when the following code works:
<cfquery datasource="yourDatasource"> INSERT INTO mailinglist (name, emailAddress) VALUES( '#form.name#', '#form.emailAddress#') </cfquery>
There are a few reasons this is bad. Communication with the database is inefficient. None of the form values have been validated to contain correct data. None of the string data has been escaped. Strings passed in can contain things like single quotes and semicolons that can cause innocent values to error upon insertion, and malicious values to delete or change information.
Now that you've seen how cfqueryparam can help you, let's take a look at the attributes.
The first attribute is value. This is the value that you want to pass into your query. If you are still using CFMX 6.0, there is an issue with using a function within this attribute, but that has been fixed in later patches.
The second attribute is CFSQLType. You have a lot of options, they are listed in Table 1. The CFSQLType is the sql type that the paramater value will ultimately bind to (see sidebar). In other words, this is the column type that was setup in your database. The max length attribute protects you from attempting to insert too large of a variable into your database. If you have a varchar(15), but you attempt to insert a string of length 25, your database throws an error. If you put a value into the max length attribute, cfqueryparam will then validate the information and throw an error before sending it the database. The errors thrown by the cfqueryparam are often easier to interpret than those thrown by the database.
The scale attribute measures the number of permitted digits after the decimal point. This only applies to CFSQLTypes CF_SQL_DECIMAL and CF_SQL_NUMERIC. This is similar to max length in that it validates the value and throws an error if it does not pass.
The null attribute determines whether the value to be inserted is NULL, meaning nothing is to be inserted. When you specify null to equal yes, then the value attribute is ignored.
The final two attributes deal with delimited lists. The list attribute identifies the passed in attribute value as a delimited list. The separator attribute specifies which delimits the list, it defaults to ','. Cfqueryparam will automatically add the necessary parenthesis and quotes to the value.
Example of use:
You have a form that has name and e-mail address, and you would like to insert it into a database. On your action page you have the code:
<cfparam name="form.name" type="string"> <cfparam name="form.emailAddress" type="string"> <cfquery datasource="yourDatasource"> INSERT INTO mailinglist (name, emailAddress) VALUES( <cfqueryparam value="#form.name#" maxlength="50" cfsqltype="cf_sql_varchar">, <cfqueryparam value="form.emailAddress#" maxlength="50" cfsqltype="cf_sql_varchar"> ) </cfquery>
cfsettings
<cfsetting enableCFoutputOnly = "Yes" or "No" showDebugOutput = "Yes" or "No" requestTimeOut = "value in seconds" >
Cfsetting is a page level control of general settings. There are only a few attributes, and each performs a unique operation. As we examine the attributes, the use of the associated settings will become clear.
The first attribute is enableCFoutputOnly. This attribute blocks any output unless it is explicitly stated within cfouput or writeOuput. In other words, if it's not in between <cfoutput> </cfoutput>, or within writeOutput(), it won't be displayed to the user. This attribute is used to eliminate the white space and generally untidy output produced by ColdFusion (or any tag based language for that matter).
The second attribute is showDebugOutput. This manually turns on and off debugging output for the current page. This is really used for turning debugging off. You have to have debugging turned on in the cf administration in order for you to be able to use showDebugOutput="yes". More effective is the cfsetting showdebugoutput="no". This is good if the debugging information is affecting your layout.
The last attribute is requestTimeOut. The first two attributes are Yes / No values, but this attribute takes the time out in seconds. This is a self-imposed time limit in which the page will time out after the specified limit. This overrides any time out settings made in the cf administrator.
Example of use:
This tag is easily adapted to be controlled via the URL. Using the following code you can change settings for your debugging on the fly via the URL.
<cfparam name="url.debug" type="boolean" value="true"> <cfparam name="url.timeout" type="numeric" value="20"> <cfparam name="url.cfoutputonly" type="boolean" value="false"> <cfsetting showdebugoutput="#url.debug#" enablecfoutputonly="#url.cfoutputonly#" requestTimeOut="#url.timeout#">
cfsavecontent
<cfsavecontent variable = "variable name"> content </cfsavecontent>
Cfsavecontent is an easy tag that is really useful. It saves the content rendered in between the pair of tags to the variable specified in the attribute. This tag is used for variable assignment, like cfset. Instead of <cfset varaible = "value">, the value is placed between the cfsavecontent tags instead of quotation marks.
This tag has a lot of applications. It's good for setting variables containing large amounts of text. It improves readability for long expressions. By surrounding the value with tags, you eliminate issues of escaping quotation marks. Another good application of this is putting javascript in here.
If your web applications make use of including templates, you have noticed that sometimes certain elements require a javascript function. Using cfsavecontent, it's easy to keep this javascript code organized. The code is outputted at the top of your page, instead of placing the javascript in the middle of your page whenever you need it.
Example of use:
Here we have a variable that will contain a hyperlink. The hyperlink calls a javascript function to open a browser window. We can't easily use cfset because the link contains single and double quotes. Using cfsavecontent we do not have that problem
<cfsavecontent variable="popUpLink">
<a href="javascript://" onclick="MM_openBrWindow
('http://www.test.com','test','width=200,height=75')">test</a>
</cfsavecontentcfsilent
<cfsilent>
... </cfsilent>
Cfsilent is an easy tag with no attributes, so let's get right into its functionality. All output is suppressed between a pair of cfsilent tags. Even if you have <cfoutput> or writeOutput(), it won't display anything.
So why do we want to suppress white space? It's all about the final display. Cfsilent helps combat rendered pages that have a lot of extra space. This is because ColdFusion is a tag-based language, and it renders output not necessarily in the CFML language. So even though you don't have any code, you still have line returns that are output.
Example of use:
Here we are performing some operations and variable assignment. Nothing is being displayed, so we will place it between cfsilent to tidy up the final output.
<cfsilent> <cfparam name="url.action" default=""> <cfif len(url.action)> ... <cfelse> ... </cfif> <cfloop> ... </cfloop </cfsilent>
cfdump
<cfdump var = "#variable#" expand = "Yes or No" label = "text">
Cfdump outputs the value of the variable in a nicely formatted version. The difference between <cfoutput>#variable#</cfoutput> and cfdump is that you can output complex variables like queries or even objects. A bit of warning first: don't use this is as part of your final application. Cfdump is used strictly as part of your debugging process to expose variables.
Let's dig into the parameters a bit more.
The first attribute is var. This takes a ColdFusion variable surrounded by pound signs. The pound signs are important. If you call this tag with var="myvariable" instead of var="#myvariable#", it's going to output the string "myvariable", and not the value contained within the variable of the same name.
The second attribute is expand. This takes either a Yes or No. When cfdump outputs complex variables such as structs, XML, or queries it generates collapsible DHTML. The individual branches and sub variables can be expanded and contracted to allow you to drill down the data. When set to yes, the variable will be fully expanded. When set to no, it will be contracted.
This is useful when dumping more than one large complex variable type. For example if you had 4 queries with up to 20 rows in each, if you dumped them all expanded that would take up a large amount of space. So you would want to dump them contracted and just click on the queries as you want to explore them.
The last parameter is label. This takes a string that titles the output.
Example of use:
This is a form action page that processes and inserts the passed information into the database. After looking at the database you have determined that there is an issue with this page. Your first step is look at the data that is being sent in, so you cfdump the form scope and abort processing so you can take a closer look at the data:
Top of page:
<cfdump var="#form#"><cfabort>
Conclusion
You now have six new tags in your ColdFusion toolbelt. Start implementing them into your existing code and new projects. You will find that after using each a few times, they come quite easily and you won't remember how you ever lived without them.