When you have to bugfix, extend or review a coldfusion application, there's a good chance you find yourself browsing in a directory tree representing the navigation on the site. Within these directories, typically some 40 or 50 files with names like list.cfm, insertform.cfm, insertaction.cfm etc.. reside.
You know you gonna be in trouble, because as so often happens, your customer does not know exactly what he wants, or where he wants it. And now he wants this specific part of the site to reside in another part of the site, or more parts, ... with security on it... and with some extra functionality, and... oh, we don't have enough budget for more.
Without even taking a look at the code, you know you gonna have to redo a lot of links (yes yes, they were linked dynamically, but the way it's tied up together now it's just not possible to make it work within the context of the new location on the site).
If you start feeling a little guilty about now, knowing you use to write code like this too, and you are worried about the mental state of the guy who needs to look into your code afterwards, for any reason, here's a small tutorial about a fairly simple technique which i use often and does the job. It ain't exactly fusebox (which i can recommend to you all, this technique works fine as a fuse too), but it is proper coding and it gets the job done.
Let's kick off.
The one and only think i actually have to tell you is to create all your links like:
<a href="#cgi.script_name#?#ReplaceList(cgi.query_string,'&mm_action=#URL.mm_action#,&mm_language=
#URL.mm_language#','&mm_action=view,&mm_language=#form.mm_selected_language#')#>link</a>
What exactly do i mean by this?
Every hyperlink you create in this module posts to itself, keeping all url variables intact. The ReplaceList carefully strips all the URL variables you wish to change, so that your next call to the module meets the settings you intend in this hyperlink.
The most important thing here is that pressing the hyperlink doesn't affect any other code which may be executed out of your module's scope. Hence, we can plug the module anywhere.
Some Practical remarks:
We try to replace URL variables which may or may not exist.
Presetting these variables not only saves is from writing a lot of extra isdefined checks, but placing all these variables on top of the module gives is a quick and easy glance of all the different behavours this module contains and we can get a good idea of what the module does, even without looking at the code, so as an example i 'm gonna preset some URL variables:
<!--- Sample MyModule --->
<cfparam name="URL.mm_id" default="">
<cfparam name="URL.mm_action" default="view">
<cfparam name="URL.mm_language" default="EN"><!--- set default language to English --->
<cfparam name="URL.mm_currency" default="EU"><!--- set default currency to Euro --->
Why the mm_ ????
Well, the mm is derived from the module's name: MyModule. Imagine we place this module next to another module which also contains a 'action' variable, i don't want the modules to infet each other's variable settings, so by preceeding the variable name with a abbreviation of the module's name, we have a good chance the module's will not conflict.
The code i paste below is a sample module in which i try to show in code what i explained above. The code is not tested, i just wrote it top-to-bottom, but you will get the picture, and hey, i 'm convinced you learn more from a sample peace of code that may throw an occasional error, so you have to investigate the code, then just plug working sample code and change some static text without looking at how it really works.
<!--- Sample MyModule --->
<cfparam name="URL.mm_id" default="">
<cfparam name="URL.mm_action" default="view">
<cfparam name="URL.mm_language" default="EN"><!--- set default language to English --->
<cfparam name="URL.mm_currency" default="EU"><!--- set default currency to Euro --->
<!--- switch language --->
<cfif URL.mm_action EQ 'switch_language'>
<!--- for simplicity, we presume a language code has been posted from a form dropdown --->
<cfif IsDefined('form.mm_selected_language')>
<cflocation url="#cgi.script_name#?#ReplaceList(cgi.query_string,'&mm_action=#URL.mm_action#,&mm_language
=#URL.mm_language#','&mm_action=view,&mm_language=#form.mm_selected_language#')#" addtoken="no">
</cfif>
<!--- switch language --->
<cfelseif URL.mm_action EQ 'switch_currency'>
<!--- for simplicity, we presume a currency code has been posted from a form dropdown --->
<cfif IsDefined('form.mm_selected_language')>
<cflocation url="#cgi.script_name#?#ReplaceList(cgi.query_string,'&mm_action=#URL.mm_action#,&mm_language
=#URL.mm_language#','&mm_action=view,&mm_language=#form.mm_selected_language#')#" addtoken="no">
</cfif>
<!--- default behaviour --->
<cfelseif URL.mm_action EQ 'view'>
<cfinclude template="qry_getItems.cfm"><!--- query contains selected language and currency in where clause --->
<cfinclude template="dview.cfm">
<!--- search form --->
<cfelseif URL.mm_action EQ 'search'>
<form method="post" action="#cgi.script_name#?#ReplaceList(cgi.query_string,'&mm_action=
#URL.mm_action#','&mm_action=search_action')#">
...
</form>
<!--- search action --->
<cfelseif URL.mm_action EQ 'search_action'>
<cfinclude template="qry_searchItems.cfm"><!--- query contains selected form.searchstring, language and currency in where clause --->
<cfinclude template="dview.cfm">
<!--- add Item (display form) --->
<cfelseif URL.mm_action EQ 'add'>
<form method="post" action="#cgi.script_name#?#ReplaceList(cgi.query_string,'&mm_action=
#URL.mm_action#','&mm_action=add_action')#">
...
</form>
<!--- add Item (insert the form values with a query) --->
<cfelseif URL.mm_action EQ 'add_action'>
<cfinclude template="qry_insertItem.cfm">
<cflocation url="#cgi.script_name#?#ReplaceList(cgi.query_string,'&mm_action=#URL.mm_action#','&mm_action=view')#" addtoken="no">
</cfif>
discuss this topic to forum
