Using Mapped Views in ColdBox

Posted on April 14, 2008 at 3:55 PM in ColdBox, ColdFusion

I don't know about you guys, but there are a number of simple, boring view files that are identical across multiple applications. One such example would be a standard user login form. Nothing fancy - it's the same on pretty much all websites. In the past I have always done the ol' copy/paste for these files and had them residing in the directory structure of each application that they were needed in. Well, thanks to ColdBox those days are now gone forever in QuackApps.

"So what's the trick, Quack?" you ask. Simple: the Request Context Decorator in ColdBox.

What I Wanted

In my handler methods, I wanted the ability to use a forward slash (/) at the beginning of my view name in order to declare an external (mapped) view. For instance, the following is the conventional way of setting the view in your ColdBox handler...

  1. e.setView("loginForm");

By convention, ColdBox will look in your app's "views" directory for a file named 'loginForm.cfm'.

Instead, I wanted to be able to do it this way...

  1. e.setView("/myMappedViews/loginForm");

The Solution: RequestContextDecorator

With this powerful feature, you are just four short and simple steps (made even shorter and simpler since you can now copy/paste) away from being able to do this very same thing in your applications.

Step 1: Create an external view proxy file, and place it in the 'views' directory of your application. (Download the attachment.)

Step 2: Create the decorator and place it in either your application's 'model' directory, or a mapped location. I chose to name mine very simply, RequestContext, and it is placed in a mapped directory named 'cbDecorators'.

Step 3: Add the RequestContextDecorator setting to your coldbox.xml file.

  1. <Setting name="RequestContextDecorator" value="cbDecorators.RequestContext" />

Step 4: Write our decorated 'setView()' method. Here it is for you, already written.

  1. <!--- BEGIN setView() method --->
  2. <cffunction name="setView" access="public"
  3. returntype="void"
  4. hint="I Set the view to render in this request.I am called from event handlers. Request Collection Name: currentView, currentLayout"
  5. output="false">
  6. <!--- set the method arguments --->
  7. <cfargument name="name"
  8. type="string"
  9. required="true"
  10. hint="The name of the view to set. If a layout has been defined it will assign it, else if will assign the default layout. No extension please">
  11. <cfargument name="nolayout"
  12. type="boolean"
  13. required="false"
  14. default="false"
  15. hint="Boolean flag, wether the view sent in will be using a layout or not. Default is false. Uses a pre set layout or the default layout.">
  16. <cfargument name="cache"
  17. required="false"
  18. type="boolean"
  19. default="false"
  20. hint="True if you want to cache the view.">
  21. <cfargument name="cacheTimeout"
  22. required="false"
  23. type="string"
  24. default=""
  25. hint="The cache timeout">
  26. <cfargument name="cacheLastAccessTimeout"
  27. required="false"
  28. type="string"
  29. default=""
  30. hint="The last access timeout">
  31. <cfscript>
  32. if ( left(arguments.name, 1) IS "/" ) {
  33. setValue("extView", arguments.name & ".cfm");
  34. arguments.name = "extView";
  35. }
  36. super.setView(argumentCollection: arguments);
  37. </cfscript>
  38. </cffunction>
  39. <!--- END setView() method --->

What we are doing here is pretty straight-forward:

a) Intercept our handlers' call to setView()

b) Check to see if the view name begins with a slash (/). If yes, we add a variable named "extView" to the request collection, setting it to the passed-in view name, and then rename the view name (arguments.name) to 'extView'.

c) Pass the processing back off to the framework's setView() method for standard processing.

We have changed absolutely nothing whatsoever in the framework itself, and the only thing that is different is the framework will now call our external view proxy that we created in Step 1 above, which will then display our external, mapped view! Now it's a piece of cake to keep all of those monotonous views in one single location and use them in any and all apps that you need to. I dig it!

NOTE: For users of ColdBox 2.6 and greater, you are encouraged to use getRequestContext() in place of the super keyword. Here is the replacement line:

  1. getRequestContext().setView(argumentCollection: arguments);

That's all there is to it, folks. Yet another task made simple by the power of ColdBox!

Thanks to Luis Majano for yet another powerful feature, and for taking a few moments out of his busy schedule to say "look into the Request Context Decorator"! :-)

(For more details on the RequestContextDecorator, be sure to check out the guide.)

Comments
(Comment Moderation is enabled. Your comment will not appear until approved.)

On 4/14/08 at 7:21 PM, sal said:

very cool.

cheers
CodeBassRadio

Latest Articles

Eventually something really brilliant and witty will appear right here.

Calendar

April 2024
S M T W T F S
« Mar  
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Subscribe

Enter a valid email address.

The Obligatory Wish List