ColdFusion provides techniques for executing custom tags, including handling end tags and processing body text.
When a custom tag page executes, ColdFusion keeps data related to the tag instance in the thisTag structure. You can access the thisTag structure from within your custom tag to control processing of the tag. The behavior is similar to the File tag-specific variable (sometimes called the File scope).
ColdFusion generates the variables in the following table and writes them to the thisTag structure:
Variable |
Description |
---|---|
ExecutionMode |
Contains the execution mode of the custom tag. Valid values are "start", "end", and "inactive". |
HasEndTag |
Distinguishes between custom tags that are called with and without end tags. Used for code validation. If the user specifies an end tag, HasEndTag is set to true; otherwise, it is set to false. |
GeneratedContent |
Specifies the content that is generated by the tag. This includes anything in the body of the tag, including the results of any active content, such as ColdFusion variables and functions. You can process this content as a variable. |
AssocAttribs |
Contains the attributes of all nested tags if you use cfassociate to make them available to the parent tags. For more information, see High-level data exchange. |
The following example accesses the ExecutionMode variable of the thisTag structure from within a custom tag:
<cfif thisTag.ExecutionMode is 'start'>
The preceding examples of custom tags in this topic all reference a custom tag by using just a start tag:
<cf_date>
In this case, ColdFusion calls the custom tag page date.cfm to process the tag.
However, you can create custom tags that have both a start and an end tag. For example, the following tag has both a start and an end tag:
<cf_date> ... </cf_date>
ColdFusion calls the custom tag page date.cfm twice for a tag that includes an end tag: once for the start tag and once for the end tag. As part of the date.cfm page, you can determine if the call is for the start or end tag, and perform the appropriate processing.
ColdFusion also calls the custom tag page twice if you use the shorthand form of an end tag:
<cf_date/>
You can also call a custom tag using the cfmodule tag, as shown in the following example:
<cfmodule ...> ... </cfmodule>
If you specify an end tag to cfmodule, then ColdFusion calls your custom tag as if it had both a start and an end tag.
Determining if an end tag is specified
You can write a custom tag that requires users to include an end tag. If a tag must have an end tag provided, you can use thisTag.HasEndTag in the custom tag page to verify that the user included the end tag.
For example, in date.cfm, you could include the following code to determine whether the end tag is specified:
<cfif thisTag.HasEndTag is 'False'> <!--- Abort the tag---> <cfabort showError="An end tag is required."> </cfif>
Determining the tag execution mode
The variable thisTag.ExecutionMode contains the mode of invocation of a custom tag page. The variable has one of the following values:
If an end tag is not explicitly provided, ColdFusion invokes the custom tag page only once, in Start mode.
A custom tag page named bold.cfm that makes text bold could be written as follows:
<cfif thisTag.ExecutionMode is 'start'> <!--- Start tag processing ---> <B> <cfelse> <!--- End tag processing ---> </B> </cfif>
You then use this tag to convert the text to bold:
<cf_bold>This is bold text</cf_bold>
You can also use cfswitch to determine the execution mode of a custom tag:
<cfswitch expression=#thisTag.ExecutionMode#> <cfcase value= 'start'> <!--- Start tag processing ---> </cfcase> <cfcase value='end'> <!--- End tag processing ---> </cfcase> </cfswitch>
Considerations when using end tags
How you code your custom tag to divide processing between the start tag and end tag depends greatly on the function of the tag. However, use the following rules to help you make your decisions:
Body text is any text that you include between the start and end tags when you call a custom tag, for example:
<cf_happybirthdayMessge name="Ellen Smith" birthDate="June, 8, 1993"> <p> Happy Birthday Ellen!</p> <p> May you have many more!</p> </cf_happybirthdayMessge>
In this example, the two lines of code after the start tag are the body text.
You can access the body text within the custom tag using the thisTag.GeneratedContent variable. The variable contains all body text passed to the tag. You can modify this text during processing of the tag. The contents of the thisTag.GeneratedContent variable are returned to the browser as part of the tag's output.
The thisTag.GeneratedContent variable is always empty during the processing of a start tag. Any output generated during start tag processing is not considered part of the tag's generated content.
A custom tag can access and modify the generated content of any of its instances using the thisTag.GeneratedContent variable. In this context, the term generated content means the results of processing the body of a custom tag. This includes all text and HTML code in the body, the results of evaluating ColdFusion variables, expressions, and functions, and the results generated by descendant tags. Any changes to the value of this variable result in changes to the generated content.
As an example, consider a tag that comments out the HTML generated by its descendants. Its implementation could look like this:
<cfif thisTag.ExecutionMode is 'end'> <cfset thisTag.GeneratedContent ='<!--#thisTag.GeneratedContent#-->'> </cfif>
Within a custom tag, you typically perform error checking and parameter validation. As part of those checks, you can choose to abort the tag, using cfabort, if a required attribute is not specified or other severe error is detected.
The cfexit tag also terminates execution of a custom tag. However, the cfexit tag is designed to give you more flexibility when coding custom tags than cfabort. The cfexit tag's method attribute specifies where execution continues. The cfexit tag can specify that processing continues from the first child of the tag or continues immediately after the end tag marker.
You can also use the method attribute to specify that the tag body executes again. This enables custom tags to act as high-level iterators, emulating cfloop behavior.
The following table summarizes cfexit behavior:
Method attribute value |
Location of cfexit call |
Behavior |
---|---|---|
ExitTag (default) |
Base page |
Acts like cfabort |
ExecutionMode=start |
Continue after end tag |
|
ExecutionMode=end |
Continue after end tag |
|
ExitTemplate |
Base page |
Acts like cfabort |
ExecutionMode=start |
Continue from first child in body |
|
ExecutionMode=end |
Continue after end tag |
|
Loop |
Base page |
Error |
ExecutionMode=start |
Error |
|
ExecutionMode=end |
Continue from first child in body |