Tags

ColdFusion tags tell the ColdFusion server that it must process information. The ColdFusion server only processes tag contents; it returns text outside ColdFusion to the web server unchanged. ColdFusion provides a wide variety of built-in tags and lets you create custom tags.

Tag syntax

ColdFusion tags have the same format as HTML tags. They are enclosed in angle brackets (< and >) and can have zero or more named attributes. Many ColdFusion tags have bodies; that is, they have beginning and end tags with text for processing between them. For example:

<cfoutput> 
    Hello #YourName#! <br> 
</cfoutput>

Other tags, such as cfset and cfhttp, never have bodies. All the required information goes between the beginning (<) character and the ending (>) character, as in the following example:

<cfset YourName="Bob">
Note: The cfset tag differs from other tags in that it does not have a body or arguments. Instead, the tag encloses an assignment statement that assigns a value to a variable. The cfset tag can also call a function without assigning a value to a result variable.

Sometimes, although the tag can have a body, it is unnecessary because the attributes specify all the required information. You can omit the end tag and place a forward slash character before the closing (>) character, as in the following example:

<cfprocessingdirective pageencoding="euc-jp" />

In most cases, you specify tag attributes directly in the tag using the format attributeName=" attributeValue" , as the preceding example shows. However, as an alternative, you can place all the attributes in a structure and specify the structure in a single attributeCollection attribute, using the following format:

<tagname attributeCollection="#structureName#">

When you use this format for all built-in ColdFusion tags except cfmodule, the tag must have only the attributeCollection attribute. This format is useful when you use dynamic arguments, where the number and values of the arguments to a tag can vary based on processing results. The following example shows this usage:

<!--- Configure dynamic attribute variables. ---> 
    <cfparam name="theURL" default="http://www.adobe.com"> 
    <cfparam name="resolveURL" default="yes"> 
 
<!--- Code that dynamically changes values for attributes can go here. ---> 
 
<!--- Create an arguments structure using variables. ---> 
    <cfset myArgs=StructNew()> 
    <cfset myArgs.url="#theURL#"> 
<!--- Include a user name and password only if they are available. ---> 
    <cfif IsDefined("username")> 
    <cfset myArgs.username="#username#"> 
</cfif> 
<cfif IsDefined("password")> 
    <cfset myArgs.password="#password#"> 
</cfif> 
<cfset myArgs.resolveURL="#resolveURL#"> 
<cfset myArgs.timeout="2"> 
 
<!--- Use the myArgs structure to specify the cfhttp tag attributes. ---> 
    <cfhttp attributeCollection="#myArgs#"> 
    <cfoutput> 
        #cfhttp.fileContent# 
    </cfoutput>
Note: The attributeCollection attribute used in the cfmodule tag and when calling custom tags directly is different from the attributeCollection attribute for all other tags. In the cfmodule tag and in custom tags, you can mix the attributeCollection attribute and explicit custom tag attributes. Also, in the cfmodule tag, the attributeCollection attribute cannot contain the name and template attributes. Specify these attributes directly in the cfmodule tag.

You can use the attributeCollection attribute in all tags except the following:

cfargument

cfelseif

cflogout

cfset

cfbreak

cffunction

cfloop

cfsilent

cfcase

cfif

cfparam

cfswitch

cfcatch

cfimport

cfprocessingdirective

cftry

cfcomponent

cfinterface

cfproperty

 

cfdefaultcase

cflogin

cfrethrow

 

cfelse

cfloginuser

cfreturn

 

Built-in tags

Built-in tags make up the heart of ColdFusion. These tags have many uses, including the following:

  • Manipulating variables

  • Creating interactive forms

  • Accessing and manipulating databases

  • Displaying data

  • Controlling the flow of execution on the ColdFusion page

  • Handling errors

  • Processing ColdFusion pages

  • Managing the CFML application framework

  • Manipulating files and directories

  • Using external tools and objects, including Verity collections, COM, Java, and CORBA objects, and executable programs

  • Using protocols, such as mail, http, ftp, and pop

The CFML Reference documents each tag in detail.

Custom tags

ColdFusion lets you create custom tags. You can create two types of custom tags:

  • CFML custom tags that are ColdFusion pages

  • CFX tags that you write in a programing language such as Java or C++

Custom tags can encapsulate frequently used business logic or display code. These tags enable you to place frequently used code in one place and call it from many places. Custom tags also let you abstract complex logic into a single, simple interface. They provide an easy way to distribute your code to others. You can even distribute encrypted versions of the tags to prevent access to the tag logic.

You can access a variety of free and commercial custom tags on the Adobe ColdFusion Exchange (www.adobe.com/go/learn_cfu_cfdevcenter_en). They perform tasks ranging from checking if Cookies and JavaScript are enabled on the client browser to moving items from one list box to another. Many of these tags are free and include source code.

CFML custom tags

When you write a custom tag in CFML, you can take advantage of all the features of the ColdFusion language, including all built-in tags and even other custom tags. CFML custom tags can include body sections and end tags. Because they are written in CFML, you do not need to know a programming language such as Java. CFML custom tags provide more capabilities than user-defined functions, but are less efficient.

For more information on CFML custom tags, see Creating and Using Custom CFML Tags. For information about, and comparisons among, ways to reuse ColdFusion code, including CFML custom tags, user-defined functions, and CFX tags, see Creating ColdFusion Elements.

CFX Tags

CFX tags are ColdFusion custom tags that you write in a programming language such as Java or C++. These tags can take full advantage of all the tools and resources provided by these languages, including their access to runtime environments. CFX tags also generally execute faster than CFML custom tags because they are compiled. CFX tags can be cross-platform, but are often platform-specific, for example if they take advantage of COM objects or the Windows API.

For more information on CFX tags, see Building Custom CFXAPI Tags.

Tags as functions and operators

ColdFusion provides many functions or operator language elements that correspond to CFML tags. Together with the existing CFScript language, these elements let you define many CFCs and functions entirely in CFScript.

The new functions and operators belong to the following tag categories:

  • Tags without bodies, such as cfexit and cfinclude

  • Language tags with bodies, such as cflock and cftransaction

  • Service tags with bodies, such as cfmail and cfquery

  • Tags for defining and using components and functions: cfcomponent, cfinterface, cfimport, cffunction, cfproperty, cfargument. For more information, see Defining components and functions in CFScript.

Tag without bodies

Several basic ColdFusion tags now have corresponding CFScript operators. These operators take a subset of standard tag attributes, and do not allow custom attributes. They do not return values.

The following list specifies the CFML tags and their corresponding CFScript syntax:

  • cfabort: abort ["message"];

  • cfexit: exit ["methodName"];

  • cfinclude: include "template";

  • cfparam: param [type] name [=defaultValue];

    The param attribute can now take any number of name=value pairs. Param can also take all the attributes of <cfparam> as name-value pairs.

    For example:

    <cfscript> 
    param name="paramname" default="value" min="minvalue" max="maxvalue" pattern="pattern" 
    </cfscript>
  • cfrethrow: rethrow;

  • cfthrow: throw "message";

For detailed information on the statement parameters, see the corresponding tag attribute description in the CFML Reference.

Language-level tags with bodies

ColdFusion includes CFScript elements that provide the functions of the following language (compiler)-level tags, which have bodies. These tags manage the execution of code within their bodies:

  • cflock: lock

  • cfthread: thread

  • cftransaction: transaction

Thread and transaction support also include functions, such as threadJoin and transactionCommit, that let you manage any thread or transaction, whether you define it with a tag or a function.

The lock, thread, and transaction operations have the following syntax:

operationName attributeName1=value1 attributName2=value2... 
{body contents }

cflock

The lock operation has no special characteristics or limitations. All cflock tag attributes are valid operation parameters. The following code uses the lock operation:

lock scope = "request" timeout = "30" type = "Exclusive" { 
request.number = 1; 
writeoutput("E-Turtleneck has now sold "& request.number &" 
turtlenecks!"); 
}

cftransaction

To use the transaction operation you specify a begin action parameter. A transaction has the following general form:

TRANSACTION action="begin" [isolation="isolationValue"] { 
transaction code 
}

Within the transaction block you call the following methods to manage the transaction:

  • transactionCommit()

  • transactionRollback([savepoint])

  • transactionSetSavepoint([savepoint])

The savepoint parameter is a string identifier for the savepoint.

Note: You can also use theses methods in a cftransaction tag body.

You can nest transaction operations. For more information on nested transactions, see cftransaction in CFML Reference.

The following example uses nested transaction operations:

<cfscript> 
    qry = new Query(); 
    qry.setDatasource("test"); 
    qry.setSQL("delete from art where artid=62"); 
    qry.execute(); 
    TRANSACTION action="begin" 
    {writeoutput("Transaction in cfscript test"); 
    TRANSACTION action="begin" { 
    qry.setSQL("insert into art(artid, artistid, artname, description, issold, price) 
    values ( 62, 1, 'art12', 'something', 1, 100)"); 
    qry.execute();} 
    transactionSetSavepoint("sp01"); 
    qry.setSQL("update art set artname='art45' where artid=62"); 
    qry.execute(); 
    transactionSetSavepoint("sp02"); 
    qry.setSQL("update art set artname='art56' where artid=62"); 
    qry.execute(); 
    transactionrollback("sp02"); 
    transactioncommit(); 
    } 
</cfscript>

cfthread

To use the thread operation you specify a run action parameter. The thread runs the code in the operation body. A thread block has the following general form:

THREAD name="text" [action="run"] [priority="priorityValue" 
application-specific attributes] { 
thread code 
}

The code in the thread operation body executes in a single ColdFusion thread. Code outside the body is not part of the thread. You can use the following methods to manage the thread:

  • threadTerminate(threadName)

    This function terminates the thread specified by the threadName parameter. It behaves in the same way as cfthread action="terminate".

  • threadJoin([[threadName], timeout])

    This function joins the current thread with the specified thread or threads. The current thread waits until either the specified threads complete, or the timeout period passes, whichever happens first. The current thread inside a thread function block belongs to that block thread and the current thread outside a thread function block is the page thread.The threadName parameter is a comma-delimited list specifying one or more threads to join with the page thread. If you omit this attribute, the current thread waits until all ColdFusion threads finish running.The timeout parameter specifies the maximum time, in milliseconds, the calling thread waits for the other threads to complete processing. If one or more threads do not complete before the time out period, the current thread processing begins immediately. If you omit this attribute, the current thread waits until all specified threads finish running.

    Note: You can also use these functions with transactions that you create by using cftransaction tags.

Service tags with bodies

ColdFusion provides objects, implemented as CFCs, that correspond to the following service tags:

  • cfftp

  • cfhttp

  • cfmail

  • cfpdf

  • cfquery

  • cfstoredproc

These tags have bodies and provide services such as executing queries or sending mail. Many of them have action attributes, whereas others have an implicit action, such as execute. For each service tag, except for cfmail and cfpdf, a component is returned with applicable properties set and you need to invoke getters on the properties to access the data.

Note: Previously, invoking getName() and getResult() methods returned data like query resultset, pdf object, or ftp prefix, but now this has been changed and instead a component is returned with appropriate properties set.

The object names are the tag names without the cf prefix, for example, ftp. These objects also support child tag functionality, such as cfmailpart and cfmailparam.

Note: There may be thread-safety issues if implicit setters are used and child tags such as cfmailpart or cfmailparam are added because they get added into the CFC variable scope. It is therefore recommended that you create a new component for each service. If you need to preserve the attribute state, use duplicate() on the component to retain any initialized attribute values.

To use these tags in functions you:

  1. Instantiate a service object.

  2. Set object attributes and child tags

  3. Execute one or more actions on the object.

Note: Unlike the corresponding tags, you cannot use application-specific parameters in these functions. You can only use the parameters that ColdFusion supports directly.

Step 1: Instantiate a service object

To create a function object, such as a mail object, use the new operator or createobject() function, as in the following example:

myMail = new mail(server="sendmail.myCo.com");

Step 2a: Managing attributes

You can set attributes in several ways:

  • As name=value parameters to the object initializer when you instantiate the object, as in the following example.

    myMail = new mail(server="sendmail.myCo.com");
  • As name=value parameters to an object action method, as in the following example:

    Q = myQuery.execute(sql="select * from art");
  • By using attribute setters, as in the following example:

    myMail.setSubject("Hi");
    Note: You cannot use a getAttributeName function to get the value of the attribute specified by AttributeName. Instead, use GetAttributes(AttributeName).
  • By using the following functions:

    SetAttributes(attrib1=value,attrib2=value,...); 
    GetAttributes([attribName1[,attribName2]]....); 
    ClearAttributes([attribName1[,attribName2]]...);
Note: If you specify a result attribute for a stored procedure, then calling getPrefix() returns, executionTime,statusCode,cached . If you do not specify a result attribute, getPrefix() returns only executionTime and statusCode.

Step 2b: Managing child tag operations

All service objects correspond to tags that have child tags. For example, cfmail has cfmailpart and cfmailparam child tags.

To specify the child tag functionality, use the following methods:

  • httpObj.addParam

  • mailObj.addParam

  • mailObj.addPart

  • pdfObj.addParam

  • queryObj.addParam

  • storedProcObj.addParam

  • storedProcObj.addProcResult

For example:

mailObj.addparam(file="#ExpandPath('test.txt')#"); 
mailObj.addPart(name="foo",type="html",charset="utf-8", 
body="This is a test message.");

You can also clear child tag settings by calling the following functions.

  • httpObj.clearParams

  • mailObj.clearParams

  • mailObj.clearParts

  • pdfObj.clearParams

  • queryObj.clearParams

  • storedProcObj.clearParams

  • storedProcObj.clearProcResults

If you used multiple add methods on an object, the clear method clears all values set in all the methods.

Step 3: Executing service actions

Service tags, excluding cfmail and cfpdf, have one or more actions that return results. Some, including the cfpdf and cfftp tags have action attributes. For these tags, each action corresponds to a method on the service object. For example, the ftp object action methods include open, close, listDir, getFile, rename, and many others. However, the way service tags return data has changed. Now, a component is returned with applicable properties set and you need to invoke getters on the properties to access the data.

Note: The PDF object has two action methods whose names differ from the corresponding cfftp action attribute values: getPDFInfo and setPDFInfo instead of getInfo and setInfo. This difference is required to prevent name collisions with the set and get methods for the PDF info attribute.

The cfhttp, cfmail, cfquery, and cfstoredproc tags do not have action attributes. Instead, the tags perform a single action. To perform these actions in cfscript, call the following functions:

  • httpObj.send()

  • mailObj.send()

  • queryObj.execute()

  • storedProcObj.execute()

To get an action result, you typically assign the results of the action method to a variable, as in the following example:

Q = qry.execute(sql="select * from art");
Note: The attributes that specify you for an action are valid only for that action and are cleared once the action is completed.

Service code example: mail, ftp, and http

The following example shows the use of the mail, http, and ftp services in cfscript.

<!---mail and ftp service ---> 
<cfscript> 
    m = new mail();  
<!---mail service ---> 
    m.setTo("x@adobe.com"); 
<!---set attribute using implicit setter ---> 
    m.setSubject("Hi"); 
    m.setBody("test mail"); 
<!---users need to use 'body' to specify     cfmail and cfmailpart content ---> 
    m.addparam(file="#E xpandPath('test.txt')#"); 
<!---add cfmail param tags ---> 
    m.addPart(type="html",charset="utf-8",body="some 
    mailpart content"); 
<!---add cfmailpart tags ---> 
    m.send(to="y@abc.com" ....); 
<!---attributes can be overriden when sending mail ---> 
    m.clear(); 
<!---clearAttributes(),clearParams() and clearParts() can also be used to clear ---> 
    individual items, if needed 
<!---ftp service ---> 
    f = new ftp(server="s",username="u",password="p"); 
<!---check if a specified directory already exists (note the usage of getPrefix ())---> 
    f.existsDir(directory ="some_dir").getPrefix().returnValue ? WriteOutput("Directory 
    exists"):WriteOutput("Directory does not exist"); 
    <!---list directory contents (note the usage of getResult() and getPrefix() ---> 
    r = f.listDir(directory="some_dir",name="dirContents"); 
    dirContents = r.getResult(); 
    r.getPrefix().succeeded ? WriteOutput("List Directory operation successful") : 
</cfscript> 
<!---http service ---> 
<cfscript> 
    httpObj = new http(); 
    <!---example 1 ---> 
        <!---add params---> 
        httpObj.addParam(type="cgi", Name="Content-type", value = 
        "application/x-www-form-urlencoded",encoded="no"); 
        httpObj.addParam(type="body",value="test1=value1&test2= 
        value2&arraytest=value1&arraytest=value2"); 
    <!---assign the component returned to a variable---> 
        r = httpObj.send(url="http://localhost:8500/ 
        project1/cfscript_test_files/thread-     
        safe/http/_cfhttpparam_body.cfm",method="POST"); 
    <!---use getPrefix() to dump the         cfhttp prefix ---> 
        writedump(r.getPrefix()); 
    <!---example 2 ---> 
 
    <!---using attributes that return a query ---> 
        r = httpObj.send(url="      
        http://localhost:8500/language_enhancements_2/cfscript_test_files/thread- 
        safe/http/vamsee.txt")",name="myqry", firstrowasheaders="no",method="GET"); 
    <!---dump result and name attributes data ---> 
        writedump(r.getPrefix()); 
        writedump(r.getResult()); 
</cfscript>

For cfftp, following are available getters on the returned component:

  • getPrefix()

    Returns the tag prefix cfftp, which is a struct, available after any cfftp operation

  • getResult()

    Applicable only to action="listDir

For cfhttp, following are the available getters on the returned component:

  • getPrefix()

    Returns the cfhttp prefix (struct) available after the tag has executed

  • getResult()

    Applicable only if attributes like columns, delimiter, firstrowasheaders, name, or textQualifier are specified, which direct ColdFusion to return a query object.

Query service example

<cfscript> 
    qryObj = new createObject("component","com.adobe.coldfuison.query").init(); 
    <!---r here is no longer the query recordset but a component ---> 
    r = qryObj.execute(sql="select * from art",          
    datasource="cfdocexamples",result="myresult",name="myquery"); 
    <!---new way to access the data ---> 
    resultset =r.getResult(); 
    prefixData = r.getPrefix(); 
    writedump(resultset);  
    writedump(prefixData); 
    <!---Using QoQ---> 
    qryObj.setAttributes(myquery=resultset); 
    r = qryObj.execute(sql="select * from myquery", dbtype="query"); 
    writedump(r.getResult()); 
    writedump(r.getPrefix()); 
</cfscript>

The following are the available getters on the returned component:

  • getPrefix()

    Returns the result struct available after the query has executed.

  • getResult()

    Returns the resultset returned by query (SELECT query) and throws an error for other types of SQL statements or queries (like INSERT, UPDATE, DELETE).

PDF example

Whenever any action is performed for which a name attribute is specified, the new pdf is returned back to the user.

The following code shows typical actions on a PDF.

<cfscript> 
    pdfObj = new pdf(); 
    x = pdfObj.read(source=#sourcefile#, name="PDFInfo"); 
    x = pdfObj.processddx(ddxfile="#tocddx#",inputfiles="#inputStruct#",outputfiles= 
        "#outputStruct#",name="ddxVar"); 
    x = pdfObj.addWatermark(source="#pdf1#",image="#image1#", pages="1", 
        overwrite="yes", name="test2"); 
    x = pdfObj.removewatermark(source="#pdf1#", name="temp"); 
    x = pdfObj.deletePages(source="#destfolder#dest.pdf",pages="2-4", name="deltest"); 
    pdfObj.addparam(source="#pdf1#", pages="1-2,4"); 
    pdfObj.merge(destination="#destfolder#merge-oneBigFile-5.pdf", overwrite="yes"); 
    pdfObj.thumbnail(source="#pdf1#", overwrite="yes"); 
    pdfObj.setInfo(source="#pdf1#", info="#{Author="Donald Duck"}#", 
                    destination="#destfolder#pdfinfo.pdf", overwrite="yes"); 
    pdfObj.write(source="myBook", destination="#destfolder#write1.pdf", version="1.4", 
                overwrite="yes"); 
    pdfObj.protect(source="MyPdfVar", password="adobe", permissions="none", 
                    newuserpassword="newuserpw",     newownerpassword="newownerpw"); 
</cfscript>

Storedproc example

The following code shows sample usage of the storedproc service object.

<cfscript> 
    sp = new storedproc(); 
    <!---add cfprocparam tags ---> 
        sp.addParam(TYPE = "IN", CFSQLTYPE="CF_SQL_VARCHAR", VALUE="David",        
          DBVARNAME="@firstname"); 
        sp.addParam(TYPE="IN", CFSQLTYPE="CF_SQL_VARCHAR", VALUE="Peterson", 
        DBVARNAME="@lastname", null ="yes"); 
        sp.add Param(TYPE="OUT", CFSQLTYPE="CF_SQL_INTEGER", variable="MyCount",  
          DBVARN AME="@MyCount"); 
    <!---add cfprocresult  tags ---> 
        sp.addProcResult(NAME = "home r", RESULTSET = 1); 
         sp.addProcResult( NAME = "home r2", RESULTSET = 2); 
        sp.addProcResult(NAME = "home r3", RESULTSET = 3) ; 
    <!---execute stored proc---> 
        r = sp.execute(procedure="sp_weird",datasource="some_dsn",result="r"); 
        writedump(r.getProcResultSets()); 
    <!---changed from sp.getProcResults()---> 
        writedump(r.getProcResultSets ("home r3")); 
        writedump(r.getPrefix()); 
    <!---changed from sp.getResult()---> 
        writedump(r.getProcOutVariables()); 
    <!---changed from sp.getProcVars()---> 
</cfscript>

The following are the available getters on the returned component:

  • getPrefix()

    Returns the cfstoredproc prefix (struct) available after the procedure has executed.

  • getProcResultsets()

    Returns any resultsets returned by the strored procedure.

  • getProcOutVariables()

    Returns any OUT or INOUT variables set by the procedure.