Blog

Brad Wood

August 12, 2014

Spread the word


Share your thoughts

This is the second half of our two-part conversion of a FuseBox 5.1 sample app to ColdBox MVC.  If you haven't been following our blog series on converting your legacy FuseBox apps over to ColdBox MVC you may want to back up and read the previous post first..  In that post we took a look at the different files in each version of the app.  We talked about how each framework bootstraps itself up, as well as settings and circuits/handlers.  We'll pick up right were we left off in this post and finish off the code by looking at how we converted the views, models, and error handling.

Views

ColdBox will automatically look for a view file named after your action in a folder named after your handler.  Of course, all this happens in our "/views" convention folder.  You are free to name your view files whatever you want though.  Just use the following code to tell the framework what view to include:

// Include /views/randomFolder/randomFile.cfm
event.setView( "randomFolder/randomFile" );

Our views are almost identical.  There are two main differences.  The first is that our views "get" data from the handler by accessing the readily-available rc (request collection) and prc (private request collection) scopes.  rc is used for any input from the user via FORM or URL scopes.  prc is for any other data the handler wants to pass along to the view.  The second is in how we build links.

/view/listEmails.cfm

<a href="#self##xfa.conform#">Return to Connect Form</a>

/views/list.cfm

<a href="#event.buildLink( prc.xeh.conform )#">Return to Connect Form</a>

ColdBox gives you a nice helper method in the event object to build links for you.  It automatically handles HTTPS, the base domain, app mapping, and query string.  event.buildLink() can also generate SES URLs with no changes when you have it enabled.

Layouts

ColdBox layouts are placed in a folder called /layouts by default and unless you've specified something else, will look for a file called Main.cfm.

/layouts/Main.cfm

<cfoutput>
	<html>
		<head>
			<link href="/includes/getmymail.css" rel="stylesheet" type="text/css" />
		</head>
		<body>
			#renderView()#
		</body>
	</html>	
</cfoutput>

The renderView() call is where the output from the view will be placed.

Model

Your models are your services, beans, and DAO that represent the business logic in your application.  In ColdBox, these go under a folder called /model.  I created a MailService.cfc which encapsulates getting a list of messages and getting a single message.  

/model/MailService.cfc

component singleton {
	property name="attachmentPath" inject="coldbox:setting:attachmentPath";
	property name='sessionStorage' inject='coldbox:plugin:sessionStorage';
	
	function getAllMessages( required numeric start	) {
		// Get connection Info
		var connectionInfo = sessionStorage.getVar( 'connectionInfo' );
		
		return new pop().getHeaderOnly(
			server = connectionInfo.serverName,
			username = connectionInfo.userName,
			password = connectionInfo.password,
			port = connectionInfo.serverPort,
			maxrows = connectionInfo.msgsPerPage,
			startrow = arguments.start
		);
	}
	
	function getMessage( required string uid ) {
		// Get connection Info
		var connectionInfo = sessionStorage.getVar( 'connectionInfo' );
				
		return new pop().getAll(
			server = connectionInfo.serverName,
			username = connectionInfo.userName,
			password = connectionInfo.password,
			port = connectionInfo.serverPort,
			uid = arguments.uid,
			attachmentpath = attachmentPath,
			generateuniquefilenames = true
		);
	}	
}

Note the singleton annotation at the top in the component definition.  This tells WireBox to only create one instance of this service that the entire application shares.  I'm also using properties to inject a reference to my attachmentPath setting as well as the sessionStorage plugin again.  No configuration is necessary for WireBox to find the MailService CFC since we've placed it in the /model convention folder.  Unfortunately, I found that Railo doesn't support the same script syntax for the CFPOP tag so I also created a RailoMailService.cfc file in the /model folder and created the following WireBox configuration file.

/config/WireBox.cfc

component extends='coldbox.system.ioc.config.Binder' {
	function configure() {		
		// Use this to detect the CFML engine
		var CFMLEngine = new coldbox.system.core.util.CFMLEngine(); 
		
		// Railo uses a different script syntax
		if( CFMLEngine.getEngine() == CFMLEngine.RAILO ) {
			// This will override the default MailService mappings
			map( 'MailService' ).to( 'model.RailoMailService' );		
		}
		
		// No "else" needed for Adobe CF. WireBox will simply "find" the 
		// "MailService" CFC in the "/model" folder automatically.		
	}
}

This file uses a utility built into ColdBox called CFMLEngine to detect the engine in use and conditionally overwrite the MailService mapping to point to the Railo version.

Error Handling

In the FuseBox code, there are try/catches around a lot of code in the "model" files.  If an error occurs, a custom error page is included.  

<cftry>
<cfpop  .../>
	<cfcatch>
		<cfinclude template="../view/error/connectionError.cfm" />
	</cfcatch>
</cftry>

What if an error occurs somewhere else in the request though?  What if you add new code and forget to wrap it in a try/catch.  Even worse, what if you decide to rename your error template after it's referenced everywhere?  In ColdBox, error handling is built in.  All of your code is run in a try/catch at the framework level, and there's a nice default error template that displays.  In your production settings though, you'll want to override this to a more secure page that doesn't divulge information with the customErrorTemplate setting.

customErrorTemplate = "includes/templates/oops_sorry.cfm"

You can read more about the exception handling provided to you in ColdBox here.

Conclusion

To see all the code, please visit this repo on GitHub: https://github.com/bdw429s/FuseBox-5.1-Sample-App-Conversion

This sample app was a little more involved than the last one, and hopefully everything makes sense even though I included a lot more code.  If clone the Git repo you can unzip the FuseBox code and open them side by side.  Please comment below if you have any questions or suggestions, and here's our list of handy resources:

 

 

Add Your Comment

Recent Entries

Into the Box - Updates as of June 27th, 2022

Into the Box - Updates as of June 27th, 2022

Into the Box Super Early Bird ticket pricing is over, but you can still get the Early Bird. Last week we had more episodes of the Modernize or Die Podcast - Conference Edition for ITB 2022 and announced the first 2 groups of Pre-Conference Track for Into the Box.

Gavin Pickin
Gavin Pickin
June 27, 2022
Ortus Content Digest for week of June 24th

Ortus Content Digest for week of June 24th

What has Ortus been publishing this week? We have the CFML News Podcast, more ITB Workshop Podcasts, some CFCasts and YouTube Videos, lots of Ortus and ITB Blog Posts. We have a lot more planned for next week as well

Gavin Pickin
Gavin Pickin
June 24, 2022
Online CF Meeting Series on Code Reuse, 3rd Party Libraries and Package Management

Online CF Meeting Series on Code Reuse, 3rd Party Libraries and Package Management

Gavin has presented several webinars on the Online ColdFusion Meetup with Charlie Arehart. This series was inspired by many questions from customers and community members, wanting to learn more about code reuse, when should they write their own modules, when should they use java or coldfusion/cfml packages, and why should people use CommandBox and ForgeBox vs manually handling your 3rd party and shared libraries. This series tries to go back to basics, and explain pros and cons of each approach, hopefully shedding light and demystifying 3rd party libraries, package management, CommandBox endpoint installations, and ForgeBox being the home of all CFML, not a tool for box only products and tools. Check out this blog post for all of these sessions, and links on how to view them on YouTube.

Gavin Pickin
Gavin Pickin
June 23, 2022