The other day, I was looking through someone else's ColdFusion code and the order in which they defined some of their ColdFusion tag attributes was really getting under my skin. Something about it just seemed so illogical. As I was trying to process this frustration, I turned the magnifying glass inward and reflected on some of my own ColdFusion tag conventions. What I came to realize with disappointment was that my tag attributes were just as illogical, the only difference was that I was used to my own way of doing things.
I knew something needed to be done; I needed to find some sort of reason, some sort of methodology behind my tagging conventions - otherwise, I'm just a monkey at a computer. So, I thought to myself, "What is a ColdFusion tag doing?" And, what I realized was that most ColdFusion tags are really just providing different ways to set a variable. In a way, they are all variations of the CFSet tag:
<cfset x = y />
Here, we have our tag name, CFSet, then the variable we are creating or assigning value to, X, and then the value that is being assigned, Y. The next step up from this is a method-based CFSet tag:
<cfset x = f( y ) />
This adds an "action" to the equation, but it's basically the same thing: we have our tag name, CFSet, then the variable we are creating or assigning value to, X, then the action we are performing, F, and then an additional value required for this action, Y. If you think about it, isn't this latter equation what most tags are doing? As such, I have decided to change my tagging conventions to all follow the generic order:
<cfset VariableName = Action( AdditionalValues ) />
Or, to be expanded a bit in a tagging context:
- Variable Name
- Required Attributes
- Optional Attributes
For a lot of tags, such as CFFile, CFImage, CFThread, and CFHttp where I am used to putting the action before the variable name, there's definitely going to be a bit of an adjustment period. But, I think in the long run, having a unified naming convention is going to have a serious payoff in terms of readability and maintainability.
Using the tags I just mentioned, let's take a look at some examples:
<!--- Read in file contents. ---> <cffile variable="strFileData" action="read" file="#ExpandPath( './test.cfm' )#" />
Notice that I am putting the variable name first, then the action, Read, then the required attribute, File.
<!--- Read in image contents. ---> <cfimage name="objImage" action="read" source="puppy.jpg" />
Again, I am putting the variable name first, objImage, then the action to perform, Read, then the required attribute, Source.
<!--- Run thread. ---> <cfthread name="objThread" action="run"> <cfset THREAD.Foo = "Bar" /> </cfthread> <!--- Join thread. ---> <cfthread name="objThread" action="join" />
Again, we are putting the name first, then the action.
<!--- Grab image. ---> <cfhttp result="objGet" method="get" url="http://some-image-domain.com/1517832_fef835681b_o.jpg" getasbinary="yes" useragent="FireFox" />
Again, we are putting the name first, Result, then the action, Method, then the required attributes, URL and GetAsBinary, and then the optional attribute, UserAgent.
Some of this definitely feels awkward at first. For example, I am so used to putting the URL attribute first in my CFHttp tags that seeing it as the third attribute is a bit jarring. But I don't believe that awkwardness is a bad sign - I believe that the awkward feeling is my mind trying to cast off the chains of inconsistency. My bet is that after a week of doing this, it's gonna feel very natural and well thought out.
Want to use code from this post? Check out the license.