In: Categories » Computers and technology » Programming » Using the Request Scope
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 notice
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.
Useful tools and features
related articles
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 ...
2. 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)...
3. 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...
4. 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...
5. Removing an Employee From the Database
The user must have the capability to remove employees from the database. The employee delete process is a simple combination of techniques that you have already learned, such as retrieving a record from the database, displaying that record in a template, and so on. The first page in this process is nearly identical to the employee get edit form. Create a file named EmployeeGetDeleteForm.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <html> <head> <ti...
6. Making direct links to the forms
Say that you want to modify or delete a company. Right now, you need to remember the company’s ID, go back to the launch pad, click Company Edit, and enter the company ID, all just to get to the edit form. Wouldn’t you rather click a company in the list and go directly to the edit form? ... <table> <tr> <td><b>ID</b></td> <td><b>Name</b></td> <td><b>Address</b></td> <td><b>City</b></t...
7. Using a Custom Tag
Custom tags are reusable, developer-authored extensions to the ColdFusion language. The custom tag that you create in the following parts displays today’s date in a familiar format. Create a file named TodaysDate.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <cfoutput>#DateFormat(Now(), “ddd, mmm d, yyyy”)#</cfoutput> Now() returns the current date and time, and DateFormat() reformats the date. To call your custom tag, open index.cfm, a...
