Aliaspooryorik
ColdFusion ORM Book

Composition over inheritance with ColdBox 3

As ColdBox 3 is still in development, I've turned into a bit of a version junkie and often update my ColdBox revision from the SVN server. This all works fine for me on my development box, but causes problems for other members of the development team who don't run the latest revision. Another downside to running on the bleeding edge is that any other applications I have already built tend to break.

So, how do I make sure that all members of the development team have the latest version of ColdBox? Well, typically, MVC frameworks work by having the Application.cfc extend the framework. This means you can't use per-application mappings, so can we use "Composition over Inheritance"?

Luckily ColdBox 3 has a cunning trick up it's sleeve that allows you to "bootstrap" ColdBox to your application and therefore allow per-application mapping to the ColdBox directory, that is a sub-folder inside my application folder. There is more information on the ColdBox wiki, but there isn't an example of what the Application.cfc looks like. So here is one I created using the excellent ColdFusion Builder ColdBox extension:


<!--- note, this doesn't extend coldbox.system.ColdBox --->
<cfcomponent output="false">
<cfsetting enablecfoutputonly="yes">

<cfscript>
// COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP
COLDBOX_APP_ROOT_PATH = getDirectoryFromPath(getCurrentTemplatePath());
// The web server mapping to this application. Used for remote purposes or static purposes
COLDBOX_APP_MAPPING = "";
// COLDBOX PROPERTIES
COLDBOX_CONFIG_FILE = "";
// COLDBOX APPLICATION KEY OVERRIDE
COLDBOX_APP_KEY = "";

// APPLICATION CFC PROPERTIES
this.name = Right(ReReplaceNoCase(COLDBOX_APP_ROOT_PATH,"[^A-Z]", "", "all"),64);
this.sessionManagement = true;
this.setClientCookies = true;

if ( IsDefined( "cookie.cfid" ) )
{
this.sessionTimeout = createTimeSpan(0,0,30,0);
}
else
{
this.sessionTimeout = createTimeSpan(0,0,0,1);
}

// create a mapping to the myapp/frameworks/coldbox directory
this.mappings["/coldbox"] = COLDBOX_APP_ROOT_PATH & "frameworks/coldbox";

// orm
this.datasource = "mydsn";
this.ormEnabled = true;
this.ormSettings = {};
this.ormSettings.cfclocation = "model";
this.ormSettings.flushatrequestend = false;
this.ormSettings.automanageSession = false;

if ( CGI.SERVER_NAME eq "localhost" )
{
this.ormSettings.logSQL = true;
}
</cfscript>

<!--- on Application Start --->
<cffunction name="onApplicationStart" returnType="boolean" output="false">
<cfscript>
//Load ColdBox
application.cbBootstrap = CreateObject("component","coldbox.system.Coldbox").init(COLDBOX_CONFIG_FILE,COLDBOX_APP_ROOT_PATH,COLDBOX_APP_KEY,COLDBOX_APP_MAPPING);
application.cbBootstrap.loadColdbox();
return true;
</cfscript>
</cffunction>

<!--- on Request Start --->
<cffunction name="onRequestStart" returnType="boolean" output="true">
<!--- ************************************************************* --->
<cfargument name="targetPage" type="string" required="true" />
<!--- ************************************************************* --->
<!--- BootStrap Reinit Check --->
<cfif not structKeyExists(application,"cbBootstrap") or application.cbBootStrap.isfwReinit()>
<cflock name="coldbox.bootstrap_#hash(getCurrentTemplatePath())#" type="exclusive" timeout="5" throwontimeout="true">
<cfset structDelete(application,"cbBootStrap")>
<cfset application.cbBootstrap = CreateObject("component","coldbox.system.Coldbox").init(COLDBOX_CONFIG_FILE,COLDBOX_APP_ROOT_PATH,COLDBOX_APP_KEY,COLDBOX_APP_MAPPING)>
</cflock>
</cfif>
<!--- Reload Checks --->
<cfset application.cbBootstrap.reloadChecks()>

<!--- Process A ColdBox Request Only --->
<cfif findNoCase('index.cfm', listLast(arguments.targetPage, '/'))>
<cfset application.cbBootstrap.processColdBoxRequest()>
</cfif>

<!--- WHATEVER YOU WANT BELOW --->
<cfreturn true>
</cffunction>

<!--- on Application End --->
<cffunction name="onApplicationEnd" returnType="void" output="false">
<!--- ************************************************************* --->
<cfargument name="appScope" type="struct" required="true">
<!--- ************************************************************* --->
<cfset arguments.appScope.cbBootstrap.onApplicationEnd(argumentCollection=arguments)>
</cffunction>

<!--- on Session Start --->
<cffunction name="onSessionStart" returnType="void" output="false">
<cfset application.cbBootstrap.onSessionStart()>
</cffunction>

<!--- on Session End --->
<cffunction name="onSessionEnd" returnType="void" output="false">
<!--- ************************************************************* --->
<cfargument name="sessionScope" type="struct" required="true">
<cfargument name="appScope" type="struct" required="false">
<!--- ************************************************************* --->
<cfset appScope.cbBootstrap.onSessionEnd(argumentCollection=arguments)>
</cffunction>

<!--- OnMissing Template --->
<cffunction name="onMissingTemplate" access="public" returntype="boolean" output="true" hint="I execute when a non-existing CFM page was requested.">
<cfargument name="template" type="string" required="true" hint="I am the template that the user requested."/>
<cfreturn application.cbBootstrap.onMissingTemplate(argumentCollection=arguments)>
</cffunction>

</cfcomponent>

Neat huh?


4 comments

  1. I think the code snippet has an issue. It looks encrypted?

    Comment by Aaron Greenlee – July 19, 2010
  2. The snippet is loading now. Thanks.

    Comment by Aaron Greenlee – July 19, 2010
  3. Great! I makes version changing much easier, but... don't you have problems with remote proxy. the system doesn't really accept remote calls anymore because it looks for the config in the /remote directory and changing of coldbox_app_mapping doesn't seem to do the job. or did i miss something else?

    Comment by Markus Schneebeli – September 13, 2011
  4. @Markus, I've not had that problem with using the proxy for AJAX calls. Are you using Flex remoting?

    Comment by John Whish – September 14, 2011

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.

Please subscribe me to any further comments
 

Search

Wish List

Found something helpful & want to say ’thanks‘? Then visit my Amazon Wish List :)

Categories

Recent Posts