Executing custom tags



ColdFusion provides techniques for executing custom tags, including handling end tags and processing body text.

Accessing tag instance data

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 like that of 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 the tag generates. This content 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'>

Handling end tags

The preceding examples of custom tags 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 cfmessagebox, 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:

Start
Mode for processing the end tag.

End
Mode for processing the end tag.

Inactive
Mode when the custom tag uses nested tags. For more information, see Nesting custom tags.

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:

  • Use the start tag to validate input attributes, set default values, and validate the presence of the end tag if the custom tag requires it.

  • Use the end tag to perform the actual processing of the tag, including any body text passed to the tag between the start and end tags. For more information on body text, see Processing body text.

  • Perform output in either the start or end tag; do not divide it between the two tags.

Processing body text

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 variables 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. The content 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 as follows:

<cfif thisTag.ExecutionMode is 'end'> 
    <cfset thisTag.GeneratedContent ='<!--#thisTag.GeneratedContent#-->'> 
</cfif>

Terminating tag execution

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 capability 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