Making Full Use of the Tools at Hand (Part I) : Maximizing code re-use because we hate typing!

 
Apr 10, 2000
(The Layman's Fusebox)

Written / Researched By:
Fred T. Sanders and Nat Papovich

The Tools We Never Think Of

This is the first of a three part series covering the importance of various types of snippets or templates in ColdFusion application development. Many ColdFusion programmers are not aware of tools that can save them a large amount of time and provide them with a large library of reusable code. By the end of this series, you should be aware of three types of tools available to all ColdFusion programmers that will make your job much easier.

In Part I, we will be dealing with "Document Templates," which are stored in the "New Document" section of the File menu in Studio. By the end of this article, we will have several starter templates for you to start off your collection of generic, reusable code. The author uses the Fusebox method, and as these examples are taken from his collection, most will conform to that methodology. This is in no way an attempt to sell you on the Fusebox method and is just a matter of personal taste. Hopefully, with a better understanding of Document Templates, they will become an integral part of your development style and increase the speed, accuracy, and consistency of the coding of your applications.

Why Do We Want To Use Document Templates?

Well, we all have full-page starter templates that we use on regular basis. Some good examples would be our "Application.cfm" (despite the Fusebox controversy on the matter in currently published specs, we should have one. Read the next article by Michael Dinowitz as to why), "app_globals.cfm," "app_locals.cfm," and any commonly used design layouts or stylesheets. Aside from some setting changes from application to application, these templates rarely change in overall construction. Instead of keeping them in a directory somewhere, which is what most mortals do, let's let Studio do the work for us. We'll save each of these "universal" application templates as write-protected "Document Templates," and we won't have to worry about accidentally over-writing our masters.

A Little Planning Goes a Long Way These Days

By default, all Allaire gives us is a "Custom" tab under the "New Documents" window. Since the whole purpose of creating the master templates is to make our lives and jobs easier, we need a better way to organize our newly rediscovered resource. The problem is that just having a "Custom" tab isn't good enough. We need more organization and we'll want to categorize our templates. Allaire was thoughtful enough to keep these tabs as actual sub-directories and adding new tabs is as simple as adding a new sub-directory. We'll need to use Windows Explorer to add our own tabs, or alternately we can do this from the "Local Files" Resource tab. Unfortunately, after creating our templates, we'll have to move them from the "Custom" folder to the folders we've created for them, but I guess you can't have everything.

You can make your own template directories under:

(Studio 4.0.1) "C:\Program Files\Allaire\ColdFusion Studio4\Wizards"
or
(Studio 4.5) " C:\Program Files\Allaire\ColdFusion Studio45\Wizards."

Once you "Save as Template," you will need to move them from the "Custom" folder into the subdirectory you have chosen. Hopefully, you can now see the importance of this tool, and will begin using it to its full potential.

Some Starter Templates

Application.cfm
All applications should have an Application.cfm file. You will want one whether you use it or not, simply because your application will run faster. A common misconception among Fuseboxers is that we shouldn't have one, when actually what the Fusebox specs say is not to use the Application.cfm file for starting application management or to set application variables. We will, however, want the file to exist, even if it's just there with a commented line (blank Application.cfm files will crash some Application Servers).

We will be using the Application.cfm template for the speed benefit, initial application documentation, and a little extra Fusebox-specific template security. You will need to define two things in this template.

The first variable you will need to define is "request.root." This is the root of the application, not necessarily of the entire site. Since Application.cfm is not used for session management, we will actually assign a separate request.root value for each sub-application (smaller applications that are called from parent applications) as well. As an example, if you have a fusebox application in its own subdirectory (i.e., www.my-site.com/myapp), then you'll want ("request.root") to be "myapp."

Request.root is used for, but not limited to, site security. For instance, one of the Fusebox conventions is to have all applications called through the index.cfm. Let's say someone was trying to call a template directly, rather than going through index.cfm. With code using this variable, you can tell the application to redirect this user in the following ways:

1. Find an index.cfm in the directory of the template being called.

2. If there isn't one, then find an index.cfm in the immediate parent directory (which is supposed to be defined by #request.root#.)

3. If there isn't one, then go to the absolute root of the website and call that index.cfm.

Now this code has a problem, in that it will redirect while you're in development and you may not want this. Therefore, we've encapsulated all this code in a few <CFIF> statements that are based on a variable we set called "#attributes.published#." This is set by default to "NO". When we are ready to publish the application to its permanent home, we will set this to "YES" to enable the template security. If you are not using the Fusebox application framework, you'll need to modify this a bit before saving it as a "Document Template."

<!--- Application.cfm --->
<!-----------------------------------------------------------
NAME: Application.cfm
PURPOSE:
DATE CREATED:
AUTHOR:
CHANGE HISTORY:
----------------------------------------------------------->

<!--- Is this application published or still in development.
"NO" = we are developing. "YES" = we are published. --->
<CFSET ATTRIBUTES.PUBLISHED = "NO">
<CFIF NOT ISDEFINED("request.domain")>
<CFSET REQUEST.DOMAIN="#CGI.SERVER_NAME#">
</CFIF>

<!--- Set Application's Root Directory Default --->
<CFIF #ATTRIBUTES.PUBLISHED# EQ "NO">
<!--- Do nothing; we are developing. --->
<CFELSE>
<CFIF NOT ISDEFINED("request.root")>
<!--- Insert Published Application's Root/Sub Directory Name, or leave blank.--->
<CFSET REQUEST.ROOT = "">
</CFIF>
</CFIF>
<CFIF #ATTRIBUTES.PUBLISHED# EQ "NO">
<!--- Do nothing we are developing. --->
<CFELSE>
<!---
Prevents someone from directly calling a template without going through our Fusebox. This will redirect them to the first page of the application, or to an index.cfm in the directory they're sticking their nose in. If that fails, it will redirect them to the main page of our application.
--->
<CFIF FINDNOCASE("cfm",CGI.CF_TEMPLATE_PATH) AND NOT
FINDNOCASE("index.cfm",CGI.CF_TEMPLATE_PATH)>
<CFSET THISPATH = EXPANDPATH("*.*")>
<CFSET THISDIRECTORY = GETDIRECTORYFROMPATH(THISPATH)>
<CFIF FILEEXISTS(EXPANDPATH("index.cfm"))>
<CFLOCATION URL = "index.cfm?badfile=yes">
<CFELSE>
<CFIF REQUEST.ROOT IS NOT "">
<CFLOCATION URL = "/#request.root#/index.cfm?badfile=yes">
<CFELSE>
<CFLOCATION URL = "/index.cfm?badfile=yes">
</CFIF>
</CFIF>
</CFIF>
</CFIF>
<!--- end Application.cfm --->
app_globals.cfm
In Fusebox, this template is where you define all global application settings and initialize your Session and/or Client Management. You will need to define the following in this template. The Application Name. This is for your Client and Session Management. We leave client cookies off, as they aren't very efficient, users don't always have them turned on, and are generally scared of them. You will also define your Data Source Names, mail server (optional), and webmaster email address. You will want to add any other generic global settings that you commonly use for your applications. We are providing the ones that are common to almost every application.

<!--- app_globals.cfm --->

<CFSETTING ENABLECFOUTPUTONLY="Yes">

<!--- Change form and URL variables to attributes variables. --->
<!--- This is to keep with the Fusebox Standard --->
<CFIF NOT ISDEFINED("attributes.fuseaction")>
   <CF_FORMURL2ATTRIBUTES>
</CFIF>


<!--- Define Application name and turn on client and
      session management settings --->
<CFAPPLICATION NAME = "" <!--- Application Name --->
 CLIENTMANAGEMENT = "YES"
 SESSIONMANAGEMENT = "YES" 
 SETCLIENTCOOKIES = "NO">

<!--- Set some global variables --->
<CFSCRIPT>
   request.MainDSN        = ""; // Define Data Source Name
   request.MailServer      = ""; // Define Mail Server (optional)
   request.sysAdmin        = "<A HREF='MAILTO:WEBMASTER@THIS-SITE.COM'>Webmaster</A>"; // Define Administrator Email
   attributes.headerfile     = "dsp_header.cfm"; // Define our Application Header File
   attributes.footerfile      = "dsp_footer.cfm"; // Define our Application Footer File


   request.WeeklyCache    = CreateTimeSpan(7,0,0,0); // Define Cache time for queries that need updating weekly
   request.DailyCache     = CreateTimeSpan(0,1,0,0); // Define Cache time for queries that need updating daily
   request.HourlyCache    = CreateTimeSpan(0,0,1,0); // Define Cache time for queries that need updating hourly
</CFSCRIPT>

<!--- Fusebox tag for CFID and CFTOKEN in Search Engine Friendly URLs--->
<CF_FUSETOKEN>
<CFSETTING ENABLECFOUTPUTONLY="No">
<!--- end global variables --->

app_locals.cfm
This template is used for defining our application's local variables. You will have one for each application and one for each of (if any) sub applications. A good analogy for this template and the app_globals.cfm template would be to compare the differences between your driver's license and the owner's manual for your car. You need your driver's license to operate any car. This is like your "app_globals.cfm" template, which affects every application and sub-application. The owner's manual is what you need to know to drive a specific car. This is like the "app_locals.cfm" template, which is specific to only one application. In this template, we'll define our application's stylesheet. If you do not wish to do so, just delete or comment out the include. I've named it "app_style.cfm" in the template code below. If you have several stylesheets, I would just include them from "app_style.cfm," or if you have only one stylesheet, then store it there. The other four parameters to define will be the default values for your site's page title, keywords associated with the site, page description for, and possibly the search engine robot directives. We will change these settings dynamically within our fuseactions (located in our "index.cfm" template).

<!--- app_locals.cfm --->

<!--- Include Global Application Settings--->
<CFINCLUDE TEMPLATE = "app_globals.cfm">

<!--- Get Our Stylesheet --->
<!--- Optional --->
<CFINCLUDE TEMPLATE = "app_style.cfm"> 

<!--- Set Any Local Application Variables --->
<CFPARAM NAME = "request.title" DEFAULT = ""> <!--- Set Default Application Title--->
<CFPARAM NAME = "request.keywords" DEFAULT = ""> <!--- Application Keywords--->
<CFPARAM NAME = "request.description" DEFAULT = ""> <!--- Set Default Application Description--->
<CFPARAM NAME = "request.robots" DEFAULT="index,follow"> <!---(index, noindex; follow, nofollow)--->

<!--- end app_locals.cfm --->

app_layout.cfm
This is the default template used by the Fusebox BODYCONTENT tag. No changes need to be made to this template. It is simply added to the collection for convenience when starting a new project.

<!--- app_layout --->
<!--- Used In Conjuction With The Fusebox BODYCONTENT Custom Tag. --->

<CFPARAM NAME="attributes.headerfile">
<CFPARAM NAME="attributes.footerfile">
<CFPARAM NAME="request.bodycontent">
<CFPARAM NAME="attributes.showbody" DEFAULT="yes">
<CFIF LEN(ATTRIBUTES.HEADERFILE)><CFINCLUDE TEMPLATE = "#attributes.headerfile#"> </CFIF>
<CFIF ATTRIBUTES.SHOWBODY><CFOUTPUT>#request.bodycontent#</CFOUTPUT></CFIF>
<CFIF LEN(ATTRIBUTES.FOOTERFILE)><CFINCLUDE TEMPLATE = "#attributes.footerfile#"> </CFIF>

<!--- end app_layout--->
		

dsp_header.cfm
This template is just a header template. The only things you may want to change are the Meta Tags. You may also want to go ahead and fill out the HTML comment provided at the bottom with author information, etc. Remember: Only fill out what is unlikely to change. Leave all "#request.?????#" variable references alone, as we will change these dynamically within our fuseactions.

<!--- dsp_header.cfm --->
<!--- This template is used in conjunction with the BODYCONTENT Fusebox Custom Tag. --->
<CFOUTPUT>
 <!DOCTYPE HTML PUBLIC "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
 <META HTTP-EQUIV = "Content-type" CONTENT = "text/html; charset = US-ASCII">
 <!--- Help prevent Page Caching --->
 <META HTTP-EQUIV = "Expires" CONTENT = "Sun, 12 May 1996 00:36:05 GMT">
 <HTML>
 <HEAD>
 <TITLE>#request.title#</TITLE>
 <META NAME = "robots" CONTENT = "#request.robots#"> 
 <META NAME = "revisit-after" CONTENT = "5 days">
 <META NAME = "rating" CONTENT = "General">
 <META NAME = "DC.Language" SCHEME="RFC1766" CONTENT="EN">
 <META NAME = "Description" CONTENT="#request.description#">
 <META NAME = "Keywords" CONTENT="#request.keywords#">
 <LINK REL = "SHORTCUT ICON" HREF = "http://#request.domain#/favicon.ico">
 </HEAD>
 
<!-- 
Title: 
Company: 
Coded by: 
Web Address: http://www.your-site.com   <!--- replace --->
Email: webmaster@your-site.com  <!--- replace --->
-->
</CFOUTPUT>

<!--- end dsp_header.cfm --->
		

dsp_footer.cfm
This template, like the header template above, shouldn't really need changing, and this is the bare minimum required in it. What I will often do (once I've decided on a page layout) is to include everything from the end of the page body that isn't going to change, as well as the closing HTML tags for the entire document. I'm providing bare minimum here; modify any way you like.

<!--- dsp_footer.cfm --->
</HTML>
<!--- end dsp_footer.cfm--->

		

Index.cfm

This is probably one of the most important templates in this set. This is where everything comes together. All of the links in a Fusebox application point here. Other than defining your fuseactions, there is not much extra that needs to be done here. In Part II, we will build a "Fuseaction" Code Template (among others) to help speed this along.

<!--- index.cfm --->

<CFTRY>

<!--- Call Local Application Variables.--->
<CFINCLUDE TEMPLATE="app_locals.cfm">

<!--- Set our Default Fuseaction. --->
<CFPARAM NAME="attributes.fuseaction" DEFAULT="Main">

<!--- Call BODYCONTENT Fusebox Tag to define page layout. --->
<CF_BODYCONTENT>
	
<!--- 
      Set Allowable Fuseactions.
      The following CFSWITCH expression defines what fuseactions
      are allowed and what procedures to follow when a fuse-
      action is called. 
  --->
  
<CFSWITCH EXPRESSION="#attributes.fuseaction#">

  <CFCASE VALUE="Main">
     <!--- Be sure to change the following to call page layout template. We're using dsp_body.cfm. --->

     <CFINCLUDE TEMPLATE="dsp_body.cfm">
  </CFCASE>
  
  <!--- Insert Additional Fuseactions Here. --->  

<!--- Define What to do if an invalid action is called. --->  
  <CFDEFAULTCASE>
     <CFMODULE TEMPLATE="/#request.root#/index.cfm" FUSEACTION="#attributes.defaultfuseaction#">
  </CFDEFAULTCASE>

</CFSWITCH>
<!--- end of fuseaction definitions --->
</CF_BODYCONTENT>
<CFINCLUDE TEMPLATE="app_layout.cfm">
    <!--- Catch Page Errors and Display Message --->
	<CFCATCH TYPE="Any">
		<!--- You can have this do whatever you want it to do
			when an error occurs.--->
		<CFOUTPUT>#cfcatch.message#</CFOUTPUT>
	</CFCATCH>	
</CFTRY>
<!--- end of index.cfm --->

		

That's it for our Document Templates. Please stay tuned for Part II, "Code Templates," for another exciting but under-valued tool to help you on your way to faster application coding.


Privacy | FAQ | Site Map | About | Guidelines | Contact | Advertising | What is ColdFusion?
House of Fusion | ColdFusion Jobs | Blog of Fusion | AHP Hosting