Using the Request Scope

an article added by: Greg Hunter at 04052008


In: Root » Computers and technology » Programming » Using the Request Scope

French Spanish Portuguese Italian German Japanese Chinese Korean Russian Arabic

Variables within custom tags exist in their own variable space, and the only way to share data back and forth between the calling page and the custom tag is by using the Attributes and Caller scopes. Request variables are available to all templates in a request, including custom tags, and are the best way to give custom tags access to global variables such as Request.MainDSN, Request.Username, and Request.Password. You should generally restrict your use of Request-scope variables in your custom tags to global constants such as these. All other data needed by a custom tag should be passed to it via attributes. As can functions, custom tags can be called recursively. This is rare, however, and usually on an advanced scale, because recursion in custom tags is used differently than in user-defined functions. Because UDFs are more suited to making calculations, you find more numeric recursion in UDFs. On the other hand, recursion in custom tags is best suited for such procedures as recursing over structures or directory hierarchies, where the purpose is page output rather than returning single results from each recursive call. The code shows a custom tag that takes a directory path and returns a listing of all the files and subfolders of that path. It uses recursion to list the contents of subdirectories as well.

<cfparam name=”Attributes.Directory”>
   <cfoutput>
   #Attributes.Directory#\<br>
   </cfoutput>
   <cfdirectory action=”LIST”
   directory=”#Attributes.Directory#”
   name=”GetFiles”>
   <cfloop query=”GetFiles”>
   <cfif GetFiles.Type EQ “Dir”>
   <cfif GetFiles.Name NEQ “.” AND GetFiles.Name NEQ “..”>
   <cf_ListDir
   directory=”#Attributes.Directory#\#GetFiles.Name#”>
   </cfif>
   <cfelse>
   <cfoutput>
   #Attributes.Directory#\#GetFiles.Name#<br>
   </cfoutput>
   </cfif>
 </cfloop>

The CFIF test for “GetFiles.Name NEQ “.” AND GetFiles.Name NEQ “..”” is not necessary in ColdFusion MX, because MX no longer returns these values. We kept the test in this listing for backward compatibility with ColdFusion 5. ListDir.cfm uses CFDIRECTORY to get all of the files and subfolders of the directory passed to the tag. It then loops over the list of files and directories and outputs every file that it finds. Whenever the loop encounters a directory, ListDir.cfm calls itself recursively, passing the name of the new directory. We called ListDir.cfm on our systems by using the following:

<cf_ListDir Directory=”C:\inetpub\wwwroot\BibleExample”>

CFABORT is mentioned as a way to immediately stop a request’s execution. Inside a custom tag, you rarely want to end an entire request, but you may want to end the execution of the tag and return to the calling page. A call to CFEXIT looks as follows:

<cfexit method=”ExitTag”>

You have the following three possible values for method:

ExitTag: Resumes execution after the closing tag.

ExitTemplate: Resumes execution after either the opening or closing tag, depending on where it’s called.

Loop: Re-executes the body of the custom tag.

ExitTag stops the current tag, meaning that execution continues after the closing tag (or the opening tag if you have no closing tag). The codes show a custom tag and its calling page.

<cf_MyTag>
   This is the tag content.
   </cf_MyTag>
 This is content after the closing tag.
<cfif ThisTag.ExecutionMode EQ “Start”>
   This is the opening tag content.
   <cfexit method=”ExitTag”>
   This is content after the CFEXIT call.
   <cfelse>
   This is the closing tag content.
 </cfif>

Running MyTagCall.cfm produces the following:

This is the opening tag content.
   This is content after the closing tag.

Calling CFEXIT immediately skips past the closing tag, so ColdFusion skips all the extra output in the tag and calling page. ExitTemplate is similar to ExitTag; in fact, it’s different only if you call it in the Start mode. Instead of exiting the tag, ExitTag skips past the end of the current template; in other words, calling ExitTemplate in the Start mode immediately begins executing the tag body. On the other hand, calling ExitTemplate in the End mode immediately ends the custom tag.

<cfif ThisTag.ExecutionMode EQ “Start”>
   This is the opening tag content.
   <cfexit method=”ExitTemplate”>
   This is content after the CFEXIT call.
   <cfelse>
   This is the closing tag content.
 </cfif>

Calling the code now shows the following output:

This is the opening tag content.
   This is the tag content.
   This is the closing tag content.
   This is content after the closing tag.

ExitTemplate skips the end of the Start mode, but continues execution at the beginning of the body. Loop is very different from ExitTag and ExitTemplate because Loop executes code that’s already run. Rather than skipping past part of the tag, Loop re-executes the body of the custom tag. As such, it can be called only in the End mode of the custom tag. Loop is used much less often than ExitTag or ExitTemplate and is almost exclusively used with nested tags. The changes to these two tags require a change in the tag’s architecture. In the codes, OutputTable.cfm did most of the work, and OutputColumn.cfm just defined the columns to select from the database and output the header row for the listing. The modifications that you’re going to make in the following listings make OutputTable.cfm get the data from the database, but the work of outputting the data mostly falls on OutputColumn.cfm, which is a better division of labor. The codes show the modifications to OutputTable.cfm and OutputColumn.cfm.

<cfparam name=”Attributes.TableName”>
   <cfif ThisTag.ExecutionMode EQ “Start”>
   <table>
   <tr>
   <!--- Request.RowNumber contains the current row index of the
   query. I start this value at zero, meaning that OutputColumn should put
   out the header row. --->
   <cfset Request.RowNumber = 0>
   <cfelse>
   <!--- The first thing I need to do in the closing tag is put out
   the ending TR for the current row. --->
   </tr>
   <!--- I only want to perform the query once, so I check to see that
   it was the header row that was just output. --->
   <cfif Request.RowNumber EQ 0>
   <!--- I dynamically build this query based on the contents of
   ThisTag.AssocAttribs. --->
   <cfquery name=”Request.GetData”
   datasource=”#Request.MainDSN#”>
   SELECT
   <cfloop
   from=”1”
   to=”#ArrayLen(ThisTag.AssocAttribs)#”
   index=”i”>
   #ThisTag.AssocAttribs[i].ColumnName#
   <cfif i LT ArrayLen(ThisTag.AssocAttribs)>,</cfif>
 </cfloop>
FROM
   #Attributes.TableName#
   </cfquery>
   </cfif>
   <!--- I increment the current row number --->
   <cfset Request.RowNumber = Request.RowNumber + 1>
   <!--- If the new row number is still within the query’s record
   count, I begin a new table row and use CFEXIT Loop to re-execute the
   body of the custom tag, meaning that the calls to CF_OutputColumn will
   be re-run. --->
   <cfif Request.RowNumber LTE Request.GetData.RecordCount>
   <tr>
   <cfexit method=”Loop”>
   </cfif>
   </table>
 </cfif>
<cfparam name=”Attributes.ColumnName”>
   <cfparam name=”Attributes.Label” default=”#Attributes.ColumnName#”>
   <cfassociate basetag=”CF_OUTPUTTABLE”>
   <cfset ParentData = GetBaseTagData(“CF_OUTPUTTABLE”)>
   <!--- I must check to see which row to output. If Request.RowNumber is
   zero, the query hasn’t been run yet, so I output the header row.
   Otherwise, I put out the value of the current cell in the
   Request.GetData query. --->
   <cfoutput>
   <cfif Request.RowNumber EQ 0>
   <td bgcolor=”#ParentData.Attributes.HeaderRowColor#”>
   <b>#Attributes.Label#</b>
   </td>
   <cfelse>
   <td>
   #Request.GetData[Attributes.ColumnName][Request.RowNumber]#
   </td>
   </cfif>
 </cfoutput>

Notice how these listings are using Request variables? You use Request variables to communicate back and forth between the parent tag’s End mode and the nested child tags, which is another acceptable use of them. You can also do this by using CFASSOCIATE and GetBaseTagData(), but doing so would be more complicated.

legal disclaimer

Our website is not responsible for the information contained by this article. Web-articles is a free articles resource.
Suggestion: If you need fresh, daily updated content for your website, feel free to use our service. Click here for more information.

related articles

1. ColdFusion Can Be Extended In Many Ways
In addition to being one of the easiest Web-programming languages, ColdFusion is also one of the most easily extensible languages, because it can interface with many different technologies, as shown in the following list: Java objects, which are standalone packages of code written in the Java language Custom tags written in C++ or Java, which are pieces of code to be used only with ColdFusion, but which are written in either C++ or Java Java Server Page (JSP) tag libraries, which are originally built for use w...

2. First ColdFusion Application
You learn by doing, and then we go back and explain how ColdFusion worked its magic. Before you get started, though, you must learn a few terms, set up the database, and create the Web directory that you’re going to use. These are some terms that you should know: A template is a file with a .cfm extension. ColdFusion executes these templates and produces HTML that is returned to the user’s browser. A page is what appears in your browser. It is rendered from the HTML that ColdFusion Server sends back ...

3. Building the company add action template
In this article, you create the template that puts your form data into the database. Create a file named CompanyAddAction.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <cfquery name=”InsertCompany” datasource=”#Request.MainDSN#”> INSERT INTO Company( CompanyName, Address, City, State, ZipCode, Comments ) VALUES ( ‘#Trim(Form.CompanyName)#’, ‘#Trim(Form.Address)#’, ...

4. Modifying a Company in the Database
The data that CFQUERY requests from the database comes back in a result set, and the Name attribute tells ColdFusion what that result set is to be named. The SQL statement consists of three clauses: SELECT, FROM, and ORDER BY. SELECT tells the database which columns to retrieve from the database; FROM tells the database which table to retrieve those columns from; and ORDER BY tells the database how to sort the results. The result set returned from CFQUERY contains multiple rows of data, and each row has multiple columns. It would ...

5. Building the company edit action template
The code in CompanyEditAction.cfm is like the code in CompanyAddAction.cfm, but the edit action updates rather than inserts. Create a file named CompanyEditAction.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <cfquery name=”UpdateCompany” datasource=”#Request.MainDSN#”> UPDATE Company SET CompanyName = ‘#Trim(Form.CompanyName)#’, Address = ‘#Trim(Form.Address)#’, City = ‘#Trim(Form.City)...

6. Adding a New Employee to the Database
The CFQUERY in CompanyDeleteAction.cfm uses a DELETE statement with two SQL clauses: DELETE and WHERE. DELETE tells the database the table from which to delete a record, and WHERE tells the database which record to delete. You can watch the company delete process in action. Point your Web browser to http://<yourserver>/CFMXBible/Ch02/CompanyGetDeleteForm.cfm and enter a CompanyID. (To get a valid ID, go to the company list and pick a number from the ID column.) Click Submit to see the chosen company’s informatio...

7. Modifying an Employee in the Database
The DateFormat() function around the DateOfBirth column in the codereturns the employee’s birth date reformatted according to a display mask. DateOfBirth normally comes back from the database in the following format: 2002-01-01 00:00:00.0 That format is not very user-friendly. Calling DateFormat() with a mask of “mm/dd/yyyy” returns the date as follows: 01/01/2002 This version is, of course, more natural and easy to read. The same is true for the employee edit process...