Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at RIA Unleashed (Nov. 2010) with: Bob Silverberg

ColdFusion Functions Declared Inside CFScript Have Output

By Ben Nadel on
Tags: ColdFusion

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.



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.

Reply to this Comment

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?

Reply to this Comment

@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).

Reply to this Comment

@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.

Reply to this Comment

Stupid me. Of course - I see output set to false on cfcomponent. Don't feed the troll (me). Sorry ;)

Reply to this Comment

@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.

Reply to this Comment

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.

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.