Relative Custom Tag Paths: Friend or Foe?
ColdFusion 8 added support for this.mappings and this.customTagPaths as per-application settings in Application.cfc, something many developers including yours truly will tell you was a god-send.
But did you know that they can be relative?
I stumbled on this -- uh, feature? -- and I'm still undecided on whether I like it or not.
I was doing some work for a client whose production environment is on shared hosting. When working on shared hosting, I never hard-code directory paths. Today the root directory of the site might be C:\sites\clientName\www\, but if a hard drive crashes or the server is upgraded, it could switch drive letters or folder locations in the blink of an eye with no warning, and all of a sudden your applications stop working, your websites go down, and your business isn't making money.
For that reason, I make judicious use of expandPath. Not only does this protect me from lack of control of the production environment, it allows differences between development, staging, and production environments without a giant switch-block that changes all sorts of settings based on environment.
So my Application.cfc code looked something like this:
Do you see what I did wrong there? I used a relative path starting with a dot, which indicates that the path is relative to the current directory. This is syntactically correct and doesn't cause any CF errors, itself. The only reason I was surprised at all was, because of a bad assumption.
The expandPath function just translates a string to the absolute path (at runtime), and my (bad) assumption was that it would run once on application load and live for the life of the application. If this were the case, the dot wouldn't matter because the path relative to the root would be set and used throughout the site. On the contrary, it runs on every page request, and is relative to the currently executing base (more on this later) template.
Where you'll run into problems with this syntax is when you try to use a custom tag from a page in a sub-folder. For example, take the following theoretical website:
Application.cfc
index.cfm
customTags/
someTag.cfm
someFolder/
somePage.cfm
Assume that Application.cfc sets this.customTagPaths in the form I specified above, and someFolder/somePage.cfm tries to use your "someTag" custom tag, you'll get an error similar to this:
ColdFusion attempted looking in the tree of installed custom tags but did not find a custom tag with this name. If you are using per-application custom tag mappings, ensure that per-application settings are enabled by the administrator.
What's happening is that ColdFusion is looking for someFolder/customTags/somePage.cfm, which doesn't exist.
I suppose you could use this to your advantage, if you had a need for it. For instance, you might have a layout custom tag that you wrap your pages with to make sure they all have the same header, navigation, and styling; but sub-pages in folders get slightly different navigation.
Having two custom tags in two different directories that are found relative to the current template is probably a bad idea as far as maintenance is concerned though. Joe the Programmer isn't likely to notice your "." in the custom tag path, and even if he does he's not likely to realize that it means all custom tag paths are relative; unless you make heavy use of the pattern and it becomes a standard in your organization.
But, it works. I tested it by creating two custom tags that indicate who they are:
/customTags/someTag.cfm:I am the surface custom tag
/someFolder/customTags/someTag.cfm:I am the deep custom tag
And to see the results, I used the same-named custom tag from each of our two pages. I also wanted to see what would happen if I included the deep page:
/index.cfm:
/someFolder/somePage.cfm:
The output of /index.cfm was as follows, indicating that the custom tag relative to the base template was used in both cases:
I am the surface custom tag
I am the surface custom tag
And the output of /someFolder/somePage.cfm was as follows, indicating that the custom tag from the sub-folder customTags was used:
I am the deep custom tag
This brings up yet another potential issue. If you have this relative custom tag path organization in use, and later decide you need to cfinclude a sub-page onto your home page to highlight it for the week, it won't use the same custom tag that it does in the sub folder. That's not to say it will fail, because if you're clever you can again use that to your advantage.
But again, being overly clever is often more of a problem than it is a good solution. In my opinion, you're better off with one custom tags folder and two different custom tag names.
Posted in ColdFusion 8 | 2 Responses January 14 2009