When I first started using Coldfusion, I worked on a PC that was attached to a development server and a live server. Eventually, I got a laptop. I installed CF, IIS, and MSDE on the laptop so that I could develop locally. This left me with three locations to keep in synchronization. It got worse. One project wanted a copy of the application on a separate laptop that would not be connected to a network. The laptop would also be running Apache instead of IIS. Finally, I had to put a demo version of the project on a public server. This version would be used for training and would have no live data. Some areas turned off and so on. There were a few tweaks for this version as well. Another problem was software differences. The development server and live server were CF5 and I was using CFMX on my laptop. So, this left me with five versions spread over four machines deployed on two different server versions.
Uploading changes was always a pain. Of course debugging needed to be turned off on some servers. Directory paths had to change due to the application locations. Some customized features would need to be modified. Time out lengths had to be changed. This is just the top of the list.
My problem was keeping all of these applications working without modifying each file at each location. I mentioned this problem to a coworker and he said "What about CGI variables." His suggestion led me to a simple solution. In my application.cfm template, I capture the servername. Then I feed this server name into a cfswitch statement which channels it to a set of instructions for that specific template.
Here is an example from one of my application. There is a variable for an upload directory, a variable for DSN, a variable for user timeout (this is nice because it can be set for hours for the development version), a debugging variable, a flag for mailing error messages, and several other variables.
//The following two lines will keep these variables from reloading on cfincludes <cfparam name="blnApplicationVarsSet" default="no"> <cfif blnApplicationVarsSet is "no"> <cfswitch expression="#cgi.server_name#"> <cfcase value="127.0.0.1,localhost"> <cfif Find("INETPUB",ucase(cgi.path_Translated)) is not 0> <cfscript> //Upload Directory request.FileUploadPath="C:\INETPUB\WWWROOT\Test\_Images\"; //DataSource request.MyDSN="MyDB"; //Path request.path="C:\INETPUB\WWWROOT\Test\"; //Base URL request.BaseURL="http://127.0.0.1/Test/"; //Root Directory request.root="/Test/"; //How long can one be logged before being booted for inactivity. intMinutes="180"; //Display the standard debugging info? Yes or No blnShowDebugging="no"; //How long should an inactive patient remain in the waiting room? intWaitRoomMinutes="10000"; //Default Layout File request.strLayout="\Test\LayOuts\app_DefaultLayout.cfm"; //Use autologin Feature: Yes or No request.blnRememberPassword="yes"; //background color to use when values are different. request.bgcolor="pink"; //Turn email error message on or off ErrorCheck= "Off"; //Show DateTimeStamp on Reports. Yes or No blnShowDTS= "no"; //Practice blnPractice= "no"; //Use New Security System blnNewSec="yes"; //New FormPath system blnNewFormPath = "yes"; //Custom Tag Directory request.CustomTagHTTP=request.BaseURL & "CustomTags/"; </cfscript> <cfelseif Find("CFUSIONMX",ucase(cgi.path_translated)) is not 0> <cfscript> //Upload Directory request.FileUploadPath="C:\CFusionMX\WWWROOT\Test\_Images\"; //DataSource request.MyDSN="MyDB"; //Path request.path="C:\CFusionMX\WWWROOT\Test\"; //Base URL request.BaseURL="http://127.0.0.1:8500/Test/"; //Root Directory request.root="/Test/"; //How long can one be logged before being booted for inactivity. intMinutes="180"; //Display the standard debugging info? Yes or No blnShowDebugging="no"; //How long should an inactive patient remain in the waiting room? intWaitRoomMinutes="10000"; //Default Layout File request.strLayout="\Test\LayOuts\app_DefaultLayout.cfm"; //Use autologin Feature: Yes or No request.blnRememberPassword="yes"; //background color to use when values are different. request.bgcolor="pink"; //Turn email error message on or off ErrorCheck= "Off"; //Show DateTimeStamp on Reports. Yes or No blnShowDTS= "no"; //Practice blnPractice= "no"; //Use New Security System blnNewSec="yes"; //New FormPath system blnNewFormPath = "yes"; //Custom Tag Directory request.CustomTagHTTP=request.BaseURL & "CustomTags/"; </cfscript> <cfelseif Find("APACHE",ucase(cgi.path_translated)) is not 0> <cfscript> //Upload Directory request.FileUploadPath="C:\Program Files\Apache Group\htdocs\Test\_Images\"; //DataSource request.MyDSN="TestOffice"; //Path request.path="C:/Program Files/Apache Group/htdocs/Test/"; //Base URL request.BaseURL="http://127.0.0.1/Test/"; //Root Directory request.root="/Test/"; //How long can one be logged before being booted for inactivity. intMinutes="180"; //Display the standard debugging info? Yes or No blnShowDebugging="no"; //How long should an inactive patient remain in the waiting room? intWaitRoomMinutes="10000"; //Default Layout File request.strLayout="\Test\LayOuts\app_DefaultLayout.cfm"; //Use autologin Feature: Yes or No request.blnRememberPassword="yes"; //background color to use when values are different. request.bgcolor="pink"; //Turn email error message on or off ErrorCheck= "Off"; //Show DateTimeStamp on Reports. Yes or No blnShowDTS= "no"; //Practice blnPractice= "no"; //Use New Security System blnNewSec="yes"; //New FormPath system blnNewFormPath = "yes"; //Custom Tag Directory request.CustomTagHTTP=request.BaseURL & "CustomTags/"; </cfscript> </cfif> </cfcase> <cfcase value="xxx.xx.xx.yyy,xxx.xx.x.zz"> <cfif Find("PRACTICE",ucase(cgi.path_Translated)) is not 0> <cfscript> //Upload Directory request.FileUploadPath="D:\Web\TestPractice\_Images\"; //DataSource request.MyDSN="MyDBPractice"; //Path request.Path="d:\web\TestPractice"; //Base URL request.BaseURL="http://#cgi.server_name#/TestPractice/"; //Root Directory request.root="/TestPractice/"; //How long can one be logged before being booted for inactivity. intMinutes="240"; //Display the standard debugging info? Yes or No blnShowDebugging="no"; //How long should an inactive patient remain in the waiting room? intWaitRoomMinutes="720"; //Default Layout File request.strLayout="\TestPractice\LayOuts\app_DefaultLayout.cfm"; //Use autologin Feature: Yes or No request.blnRememberPassword="yes"; //background color to use when values are different. request.bgcolor="pink"; //Turn email error message on or off ErrorCheck= "On"; //Show DateTimeStamp on Reports. Yes or No blnShowDTS= "no"; //Practice blnPractice= "yes"; //Use New Security System blnNewSec="yes"; //New FormPath system blnNewFormPath = "yes"; //Custom Tag Directory request.CustomTagHTTP=request.BaseURL & "CustomTags/"; </cfscript> <cfelse> <cfscript> //Upload Directory request.FileUploadPath="D:\Web\Test\_Images\"; //DataSource request.MyDSN="TestOffice"; //Path request.Path="d:\web\Test"; //Base URL request.BaseURL="http://#cgi.server_name#/Test/"; //Root Directory request.root="/Test/"; //How long can one be logged before being booted for inactivity. intMinutes="240"; //Display the standard debugging info? Yes or No blnShowDebugging="no"; //How long should an inactive patient remain in the waiting room? intWaitRoomMinutes="720"; //Default Layout File request.strLayout="\Test\LayOuts\app_DefaultLayout.cfm"; //Use autologin Feature: Yes or No request.blnRememberPassword="yes"; //background color to use when values are different. request.bgcolor="pink"; //Turn email error message on or off ErrorCheck= "On"; //Show DateTimeStamp on Reports. Yes or No blnShowDTS= "no"; //Practice blnPractice= "no"; //Use New Security System blnNewSec="yes"; //New FormPath system blnNewFormPath = "yes"; //Custom Tag Directory request.CustomTagHTTP=request.BaseURL & "CustomTags/"; </cfscript> </cfif> </cfcase> <cfdefaultcase> <cfscript> //Upload Directory request.FileUploadPath="D:\Web\Test\_Images\"; //DataSource request.MyDSN="TestOffice"; //Path request.Path="d:\web\Test"; //Base URL request.BaseURL="http://xxx.xx.000.00/Test/"; //Root Directory request.root="/Test/"; //How long can one be logged before being booted for inactivity. intMinutes="240"; //Display the standard debugging info? Yes or No blnShowDebugging="no"; //How long should an inactive patient remain in the waiting room? intWaitRoomMinutes="720"; //Default Layout File request.strLayout="\Test\LayOuts\app_DefaultLayout.cfm"; //Use autologin Feature request.blnRememberPassword="yes"; //background color to use when values are different. request.bgcolor="pink"; //Turn email error message on or off ErrorCheck="On"; //Show DateTimeStamp on Reports. Yes or No blnShowDTS="no"; //Practice blnPractice="no"; //Use New Security System blnNewSec="yes"; //New FormPath system blnNewFormPath = "yes"; //Custom Tag Directory request.CustomTagHTTP=request.BaseURL & "CustomTags/"; </cfscript> </cfdefaultcase> </cfswitch> <cfset blnApplicationVarsSet = "yes"> <cfif>
Once this cfwitch expression is set, deployment is simple. I use a program called Beyond Compare 2 that compares my working directory with a specified directory on another machine. The program shows all differnces between the directories and gives various synchronization options. The same functionality could be achieved with Dreamweavers site management functions. In fact, you could just copy your new folder over the deployed one (not recommended though).
Since this idea is pretty simple, I am sure that many people already use a similar system. There are other options as well, like the Deployment Wizard in Coldfusion Studio. I have never used any software for deployment so I don't know how the method above compares in ease of use. My method does offers a lot of flexibility for deployment, is easy to follow, and is easy to modify.
Disclaimer: The terms "Best Practice" and "Coding Standards" are subjective. This means that what is a "best practice" or a "standard" for one may be a unfit for another. I am in no way claiming that anyone should use the above code. As far as I know, this work is original. I have not intentionally copied anyone's work. Any similarity to someone else's work is unintentional.