ColdFusion Functions Declared Inside CFScript Have Output
Last night, I was talking shop with Simon Free. He mentioned that he always writes his ColdFusion user defined functions (UDFs) in CFScript tags. I argued that if you do that, you have no control over things like output. To this he said, "Of course you do, CFScript tags don't have output unless you use WriteOutput()." But then, I was asked, "What about something like OnRequest() method in Application.cfc?"
At this point, both of us were a bit unsure as to what the outcome would be. And so, today, I thought I would give this scenario a little test:
<cfcomponent
output="false"
hint="I define the application event handlers and page request settings.">
<cfscript>
THIS.Name = "CFScriptTesting";
THIS.ApplicationTimeout = CreateTimeSpan( 0, 0, 5, 0 );
// Execute pre-page logic.
function OnRequestStart( Page ){
WriteOutput( "OnRequestStart:" );
// Include the user-selected page.
VARIABLES.Include( ARGUMENTS.Page );
}
// Executes the target template.
function OnRequest( Page ){
WriteOutput( "OnRequest:" );
// Include the user-selected page.
VARIABLES.Include( ARGUMENTS.Page );
}
</cfscript>
<cffunction
name="Include"
access="private"
returntype="void"
hint="I include templates inside of CFScript.">
<!--- Define arguments. --->
<cfargument
name="Template"
type="string"
required="true"
hint="I am the template to be included."
/>
<!--- Include template. --->
<cfinclude template="#ARGUMENTS.Template#" />
<!--- Return out. --->
<cfreturn />
</cffunction>
</cfcomponent>
As you can see, the Application.cfc itself has no output. Then, I have my OnRequestStart() and OnRequest() methods include the page that the user requested. Traditionally, my OnRequestStart() method would have no output as it is designed for "pre-page" processing. My OnRequest() method, on the other hand, is designed for output and therefore would have it turned on. In a tag-based UDF situation, I would only get the template output to the screen once; however, in this CFScript scenario, I get the following output:
OnRequestStart: I am the index.cfm page.
OnRequest: I am the index.cfm page.
Notice that both the OnRequestStart() and the OnRequest() methods allow output to be pushed to the client. Notice also that this output was generated by both the WriteOutput() method as well as the Include() UDF. It looks like ColdFusion user defined functions declared inside of CFScript tags always allow output even though they lack a lot of the whitespace generation that tag based markup creates.
This is not meant to change anyone's mind about CFScript based coding; I don't see this as having any sort of negative impact. I just wanted to see how it would work.
Want to use code from this post? Check out the license.
Reader Comments
I think what I actually said about the onRequest method was that it was evil and I don't use it :-) One thing I love about doing the application file in script tags is that i find it very readable, but i think that is mostly because I use script tags a lot in my code. I think that kind of stuff comes down to personal preference.
@Simon,
OnRequest() rocks :P
This is a little off your topic, but I wish somebody could make a convincing argument for the benefits of the BGS (Big Giant Switch) approach that so many places use to build websites. I only brought it up because of the discussion you're having about using the OnRequest method of Application.cfc.
Is it really just a matter of preference?
@Mike,
To me, the big switch is all about control. However, you can keep the switch smaller by breaking it up into smaller modules that have smaller switch statements.
It's referred to as the Hub-and-Spoke model. It revolutionized the airline industry apparently and is held in high regards (from what I have been told).
@Ben: Isn't output for any function in CF set to true by default? The issue here is that you can't switch it off.
Stupid me. Of course - I see output set to false on cfcomponent. Don't feed the troll (me). Sorry ;)
@radekg,
You did not make a mistake. The output property of a component and the output property of a function are not related. One takes care of output inbetween the functions, the other takes care of output in the functions.
But you are try about it being defaulted to "on". Well, sort off. "On" is actually a bit different; it defaults to executing as a normal page.
To clarify/expand Ben's last point:
output="TRUE" is equivalent to wrapping the cffunction contents with CFOUTPUT tags.
output="FALSE" is equivalent to wrapping the cffunction contents with CFSILENT tags.
The default output value is neither true nor false, and is the same as a normal page without cfoutput or cfsilent (so content is output, but variables are not evaluated).
A little irritatingly, the attribute is a boolean, and it is not possible to specify the default behaviour - you can only set it by not specifying the attribute at all.
@Peter,
Exactly correct. Thanks for the thorough explanation.
"The output property of a component and the output property of a function are not related."
I was searching to clean whitespace in my code and was wondering where the heck they come from. Haven't thout of this! A simple cfoutput="false" cleared them out. Once again; thank you Ben :-)