In a previous post, I commented on how I discovered that using slash-delimited component paths worked in the CreateObject() function. In the comments to that post, the general sentiment was that use of this "undocumented feature" should be avoided, as it may lead to unexpected behaviors. I kind of figured that already and make it a point to stick to using dot-delimited paths.What brought this to my attention in the first place was the following example code in the Coldbox Framework Documentation:
This code used the function call getSetting("AppMapping") to dynamically get the path to the model directory of the application. In ColdBox, getSetting("AppMapping") returns the (slash-delimited) path from the site root to the root of your applcation. Since ColdBox apps can be contained in subdirectories off the root, this is a handy function for creating portable apps without having to worry about changing all your paths depending on where you are in the site heirarchy. But I don't want to use the slash-delimited path returned by getSetting("AppMapping") for my createObject calls, so what can I do?
What I ended up doing was setting a new key in the ColdBox configuration structure that returns the dot-delimited path to the application. The new key is "comMapping", short for "component mapping". I do this in my onAppInit() method that gets called on application startup (as configured in my coldbox.xml.cfm). Here is the code:
First I check if the application is in a subdirectory. If the value returned by getSetting("AppMapping") is an empty string, then we are at the site root and "comMapping" should also be an empty string. If we aren't in the site root then the comMapping path is set up by replacing all forward slashes in appMapping with dots. I also tack on a dot at the end since the appMapping value doesn't include a trailing slash. I then insert the new key and value into my settings with the setSetting() function.
So now, I can instantiate my objects with the following code:
and it will work whether my application is in the site root or in a subdirectory.
Sep 17, 2008 at 1:43 AM Hey Tony! Thanks for this post. I'm actually just dealing with something in an app that I'm currently working on. I definitely was not looking forward to (or planning on) going through my entire app and changing those values often.
To keep your model components unaware of the ColdBox framework maybe you could have the comMapping variable injected into your objects constructor or as a setter rather than calling getSetting() from within the model objects themselves. I haven't used ColdBox though, so I don't know if that is standard practice for ColdBox applications.
Thanks a lot for sharing!!
Sep 17, 2008 at 6:04 AM Hi Brian. Good point -- the model shouldn't be framework-aware. I would only use the getSetting("comMapping") call directly in my event handler CFCs (controllers). For my model components, I'll usually, as you suggested, inject a configbean containing the setting using ColdSpring.
Sep 17, 2008 at 8:30 AM Hi Tony,
Just one thing, use duck typing in handlers
<cfargument name="Event" type="coldbox.system.beans.requestContext" />
TO
<cfargument name="Event" type="Any" />
its just simply for performance.
Thanks
Sana