ColdFusion 8 Application Mappings and Sub-folders

Now that I'm on a CF8 hosting plan, I've started leveraging some of that goodness in my applications. The first thing I have implemented is application level mappings to keep my configuration files and components out of the web root. Here's how my current project layout rolls.
/project
  /config <-- Coldspring and Transfer config files
  /model <-- model components
  /root <-- web root
    /admin  <-- secure admin screens
Basically, I want to create mappings to config and model. I did a little googlin' and found a nice snippet on Sean Corfield's blog on looping over a list to build the mappings. I aped that code with a slight mod for my setup. <cfif (ListLast(CGI.HTTP_HOST,".") eq "local")>
<cfset mapPath = "../">
<cfelse>
<cfset mapPath = "../" & this.name & "/">
</cfif>

<cfloop index="p" list="config,model">
<cfset this.mappings["/" & p] = expandPath(mapPath) & p />
</cfloop>
I dev on Mac and deploy on Windows and my local folder structure is slightly different from my host. The first part of the code is just a test of whether the site is being served up locally. When on the production server, the mapped folders are in a folder with the same name as the app. This is a great alternative to using Apache Alias or Virtual Directories in IIS for mappings. That is, until I tried using the mapping from within the admin folder. Suddenly the path was not recognized. I initially thought this was a transfer issue, but that was not the case. I tried several variations and workarounds. Eventually, I figured out that the mappings were fine for files in the web root where Application.cfc resides. So why was the path not available to files in a folder below the web root? The answer was pretty simple. The admin folder had no Application.cfc, thus no mappings. Remembering another gem by Mr. Corfield regarding extending Application.cfc via a Proxy, I created an Application.cfc in the admin folder and the required proxy in the web root. Instead of repeating the code for creating the mappings with only the path prefix changed, I wrapped the creation of mappings up in a method. <cffunction name="createMappings" access="private" output="false" returntype="void">
   <cfargument name="pathPrefix" type="string" required="false" default="../">
   <cfif (ListLast(CGI.HTTP_HOST,".") eq "local")>
      <cfset variables.mapPath = arguments.pathPrefix>
   <cfelse>
      <cfset variables.mapPath = arguments.pathPrefix & this.name & "/">
   </cfif>
   <cfloop index="p" list="config,model">
<cfset this.mappings["/" & p] = expandPath(variables.mapPath) & p />
   </cfloop>
</cffunction>
And call it from the Application.cfc in the admin folder using the appropriate prefix. <cfcomponent displayname="Application" extends="ApplicationProxy">

<!--- set mappings in this directory --->
<cfset createMappings(pathPrefix="../../")>

</cfcomponent>
Application level mappings are handy, but the per directory limitation does not make for a tad more code. Overall, I think it's a small price to pay for the benefit gained.

UPDATE:

After testing this on my Windows machine, it appears that using "this.mappings" inside a method does not properly set the mappings. I've changed things around so that the createMappings() method returns a struct and I set it as a pseudo-constructor. <cfset this.mappings = createMappings(pathPrefix="../") >

2 responses so far ↓

Justin - Feb 28, 2008 at 8:14 AM

this.mapping is per application and any subfolder will use the application settings, unless there is another application.cfc overriding the application.cfc where the mappings are set.

It seems that there is something else wrong. I have to wonder if it has to do with your relative paths as I've not done that before. My mappings are all in the way of
C:\var\wwwroot\site1\ or some such thing.

See any code set above a function in a component will run each time and your relative pathing may make it so that calling it from a subfolder is making the mapping relative to the subfolder. So, the subfolder is processing the top level application.cfc from it's location, not the application.cfc location

Paul Marcotte - Feb 28, 2008 at 11:39 AM

Hi Justin,

Using expandPath() sets a full file system path. On my Mac that resolves as /Users/paul/htdocs/project/. Believe me, I dumped the mappings and tried several variations. Before I put Application.cfc in the sub-folder, the paths were not recognized. I may be wrong on this,. It's been known to happen. ;)

Leave a Comment

Leave this field empty: