Scripting a ColdFusion Application

With the release of ColdFusion 9 this past week, at MAX, we finally have full parity for cfscript with all of the cf tags. I personally prefer script when writing data access and business logic. For some it might not appear to be the sexiest feature, but I can see it making CFML much more appealing to developers from other languages.

A terrific resource, for ColdFusion developers, has always been Ray Camden's Application.cfc Reference. In giving back (and so Ray doesn't have to type it all this time), I thought I'd write an updated Application.cfc Reference, purely in cfscript. This is only the first draft, so if you find anything that should be corrected/added/removed, please let me know. I show you the code directly below, and include it in the download link at the bottom of this post. (BTW, there is code formatting in the file, it just didn't hold in the post for some reason)

/*
* ===================================================================
* COMPONENT/CLASS
* Application
*
* PURPOSE
* Defines certain ColdFusion application operating parameters, the
* Application.cfc is called on every single ColdFusion request, and
* specific methods automatically run, depending upon the order of
* events within the application lifecycle. This is an example of
* an Application.cfc written in pure cfscript. For a better under-
* standing of Application.cfc's properties and methods, please
* read the Adobe ColdFusion 9 documentation:
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-74fa.html
*
* AUTHOR
* Steve 'Cutter' Blades [C], webDOTadminATcutterscrossingDOTcom
*
* REVISIONS
* ===================================================================
* [C 10.07.09]
* Initial creation
* ===================================================================
* @output false
*/

component {

// http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7d39.html#WSc3ff6d0ea77859461172e0811cbec22c24-68e0
this.name = "ComponentTest";
this.applicationTimeout = createTimespan(0,2,0,0);
// this.clientManagement = true|false;
// this.clientStorage = "cookie|registry|[dsn]";
this.customTagPaths = ExpandPath("/tags");
// this.googleMapKey = "[Google Map API key]";
this.dataSource = "cfbookclub"; // With this I don't need to include the attribute in my cfquery tags
// this.loginStorage = "cookie|session";
// this.mappings = {mapping1="loc1",mapping2="loc2"}; /* I haven't tried this syntax yet */
this.serverSideFormValidation = false; // this is 'true' by default, but I like to write my own
this.sessionManagement = true;
this.sessionTimeout = createTimespan(0,0,20,0);
this.setClientCookies = true;
this.setDomainCookies = true;
this.scriptProtect = true;
// this.secureJSON = true|false;
// this.secureJSONPrefix = "[some couple of characters to prefix all JSON]";
// this.welcomeFileList = "[comma delimited list of file names]";
// this.smtpServerSettings = {server="10.1.93.15",username="someUserName",password="somePassword"};
this.timeout = 3000; // This overrides the CF Admin's request timeout value, in milliseconds
// this.debuggingIPAddress = "[List of IP's requiring debugging access]";
// this.enableRobustException = true|false;

/**
* FUNCTION onApplicationStart
* Runs when an application is first initialized
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d48.html
* @access public
* @returnType boolean
* @output false
*/

    function onApplicationStart() {

return true;
    }

/**
* FUNCTION onApplicationEnd
* Runs when the application times out, or when explicitly called
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d47.html
* @access public
* @returnType void
* @output false
*/

    function onApplicationEnd(required applicationScope) {

    }

/**
* FUNCTION onMissingTemplate
* Runs when a (CF) template is called that does not exist
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d2a.html
* @access public
* @returnType boolean
* @output false
*/

    function onMissingTemplate(required string targetpage) {
include "404.cfm"; // not required
return true;
    }

/**
* FUNCTION onRequestStart
* Runs at the beginning of a request, prior to the processing of
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d41.html
* the requested template.
* @access public
* @returnType boolean
* @output false
*/

    function onRequestStart(required string thePage) {
// The following is not required
param name="URL.reload" default="false";
if (URL.reload){
onSessionEnd(SESSION,APPLICATION);
onApplicationEnd(APPLICATION);
onApplicationStart();
onSessionStart();
}
// end

return true;
    }

/**
* FUNCTION onCFCRequest
* New to CF9, this function runs only at the beginning of a CFC request
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSe821657cd7d6f83f6daaa733122cf6931bb-8000.html
* @access public
* @returnType void
* @output false
*/

    function onCFCRequest(required string cfcname,required string method,required struct args) {

    }

/**
* FUNCTION onRequest
* This runs after the onRequestStart, but still prior to the requested
* template itself. This method no longer applys to CFC requests
* (see onCFCRequest() for more information)
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d43.html
* @access public
* @returnType void
* @output true
*/

    function onRequest(required string thePage) {

include ARGUMENTS.thePage; // When using this method, you must include the requested page
    }

/**
* FUNCTION onRequestEnd
* Runs after a requested template has completed it's process
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d42.html
* @access public
* @returnType void
* @output false
*/

    function onRequestEnd(required string thePage) {

    }

/**
* FUNCTION onError
* This is an application wide error handler. Best practice would be to
* write process specific error handling, but this method will help
* you trap unexpected errors for custom notification and process
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d4a.html
* @access public
* @returnType void
* @output true
*/

    function onError(required exception,required string eventname) {
writeDump({var=ARGUMENTS.exception,label=ARGUMENTS.eventname}); // not required
    }

/**
* FUNCTION onSessionStart
* Runs when a user first starts there visit to your application.
* The application will initialize if it's not currently active
* [through onApplicationStart()]. This method would also run
* prior to onRequestStart().
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d4b.html
* @access public
* @returnType void
* @output false
*/

    function onSessionStart() {

    }

/**
* FUNCTION onSessionEnd
* Runs when a user's session times out, or when explicitly called
* http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d40.html
* @access public
* @returnType void
* @output false
*/

    function onSessionEnd(required struct sessionScope,required struct appScope) {

    }

}

There you go! Enjoy! Stay tuned, as I have more ColdFusion 9 goodies on the way...

TweetBacks
Comments
Andrew Scott's Gravatar ColdFusion 9 does not have full tag support in script, but boy is it damn close.
# Posted By Andrew Scott | 10/8/09 2:23 AM
John Whish's Gravatar I haven't had my morning cup of coffee yet, but in your onApplicationEnd() method, you're referencing the Application scope. Shouldn't you be referencing argument.applicationScope? Also, these scopes are ending so presumably you don't need to call StructClear anyway. The same applies to your onSessionEnd() method.
# Posted By John Whish | 10/8/09 3:51 AM
Steve 'Cutter' Blades's Gravatar @John

Good catch John. Interesting Note: that doesn't thow any errors either. I'll get that fixed. And yes, the scope should clear itself out. Have to stop coding when I should be sleeping;)
# Posted By Steve 'Cutter' Blades | 10/8/09 6:10 AM
John Whish's Gravatar @steve - I've been caught in the "I'll just finish this off before I stop" trap :)

I did once mistyped a variable in the onApplicationEnd() method and would get random error reports when I knew the site had no visitors on it. It was because the method is only fired when the application scope expires that the method is fired, so you'll never see an error in your browser.
# Posted By John Whish | 10/8/09 10:03 AM
Phillip Senn's Gravatar Scriptprotect values are: none,all or a comma-delimited list of scopes.
# Posted By Phillip Senn | 11/9/09 7:49 PM
Phillip Senn's Gravatar These two commands should be in some sort of reinit as well:

ormReload();
applicationStop();
# Posted By Phillip Senn | 11/9/09 8:11 PM
Guust Nieuwenhuis's Gravatar Some ORM settings to add:

this.ormenabled = true|false; // enable/disable ORM
this.ormsettings = [The struct that defines all the ORM settings.] // see http://tinyurl.com/ormsettings
# Posted By Guust Nieuwenhuis | 11/10/09 3:31 AM
Russ S.'s Gravatar Why couldn't I find this before!? If I had known it was done before I would've done something else for my "Best of CF9" entry. I was googling keywords like "cfscript application.cfc"...
# Posted By Russ S. | 12/31/09 1:45 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.3.006. Contact Blog Owner. Layout inspired by bluerobot.com., with some JQuery thrown in for fun.