Skip to main content
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: Raul Delgado
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: Raul Delgado

Using Relative File Paths To Configure Application Mappings In Lucee CFML 5.3.8.201

By
Published in Comments (2)

Historically, Adobe ColdFusion was never very friendly to relative file paths on the server - a relative file path always seemed to point to a different folder than the one in which my script was executing. Lucee CFML, on the other hand, has made it a point to be much more intuitive when it comes to relative file paths. Since switching to Lucee CFML, I've come to love this relative file path behavior when performing file I/O; however, it only just occurred to me that this same behavior may also work when configuring Application Mappings within the Application.cfc file. As such, I wanted to compare the current Adobe ColdFusion behavior to the current Lucee CFML 5.3.8.201 behavior.

Before we look at the relative path behavior, let's quickly talk about what I used to have to do in my Application.cfc file. Historically, I would have to use ColdFusion's native path-functions to find the directory in which my Application.cfc file lived. Then, I'd have to build my mappings relative that that directory. The code looked something like this:

component
	output = false
	hint = "I define the application settings and event handlers."
	{

	// Define the application settings.
	this.name = "AppMappingsDemo";
	this.applicationTimeout = createTimeSpan( 0, 1, 0, 0 );
	this.sessionManagement = false;

	// Setup the application mappings that can be used in server-side file access paths:
	// things like the expandPath() function, the include tag, and the module tag can all
	// consume mappings in order to create some abstraction around the file-system.
	this.root = getDirectoryFromPath( getCurrentTemplatePath() );
	this.mappings2 = {
		"/root": this.root,
		"/up-one": ( this.root & "../" ),
		"/down-one": ( this.root & "vendor/" )
	};

}

Notice that I am using the getDirectoryFromPath() and getCurrentTemplatePath() functions in order to find the file-system location of the Application.cfc template; and then using that value to build-out the mappings structure. This isn't super complicated; but, it's a point-of-friction; and, it represents some additional processing that has to be done on every single page request that runs through your ColdFusion application.

Now, let's compare that Adobe ColdFusion Application.cfc to a Lucee CFML Application.cfc that leverages Lucee's friendly take on relative file paths:

component
	output = false
	hint = "I define the application settings and event handlers."
	{

	// Define the application settings.
	this.name = "AppMappingsDemo";
	this.applicationTimeout = createTimeSpan( 0, 1, 0, 0 );
	this.sessionManagement = false;

	// Setup the application mappings that can be used in server-side file access paths:
	// things like the expandPath() function, the include tag, and the module tag can all
	// consume mappings in order to create some abstraction around the file-system. In
	// this case, notice that I am using RELATIVE FILE PATHS to define the mappings.
	this.mappings = {
		"/root": "./",
		"/up-one": "../",
		"/down-one": "vendor/"
	};

	// NOTE: Historically, with Adobe ColdFusion, I've had to configure mappings using
	// much more complicated path-parsing since Adobe ColdFusion doesn't like using
	// relative file-paths for anything server-side related (except the include tag).

}

Notice how much cleaner my mappings structure is when I can use file paths that are relative the Application.cfc. But, does it work?! To test this, I am going to output the expandPath() version of each one of these mappings at various folder-depths within the application. Here's my root index.cfm file:

<cfoutput>

	<h1>
		In Root - #server.coldfusion.productName#
	</h1>

	<dl>
		<dt><code>/root</code></dt>
		<dd>#expandPath( "/root" )#</dd>

		<dt><code>/up-one</code><dt>
		<dd>#expandPath( "/up-one" )#</dd>

		<dt><code>/down-one</code><dt>
		<dd>#expandPath( "/down-one" )#</dd>
	</dl>

	<!---
		In order to make sure that the location of the SCRIPT isn't somehow influencing
		the way the expandPath() is interacting with the Application.cfc mappings, let's
		try to output the same mapping values in a few folders at various depths within
		the folder hierarchy. Both of the following files have the same DL as above.
	--->
	<iframe
		src="./sub/index.cfm"
		style="display: block ; width: 100% ; height: 182px ;">
	</iframe>
	<iframe
		src="./sub/sub/index.cfm"
		style="display: block ; width: 100% ; height: 182px ;">
	</iframe>

</cfoutput>

Notice that I have a definition list (<dl>) of path values. And, that I have two iframes. Each of the iframes outputs the same definition list; only, it performs the output in sub-folders of the application.

Now, it should be noted that I am running my test servers at the following location:

/Users/bennadel/Sites/testing-lucee/

And, that this experiment is, itself, in a sub-folder of the server:

/Users/bennadel/Sites/testing-lucee/app-mappings/wwwroot/

With that said, let's render this page in Lucee CFML 5.3.8.201:

Application mappings successfully using relative file paths in Lucee CFML.

As you can see, even though our Application.cfc is located in a sub-folder of the running server; and, even though we are consuming the application mappings in even deeper folders within the file-system; all of the mappings just work when using intuitive relative file paths.

Sweet, sweet chickens!

Now, let's run the same exact page in Adobe ColdFusion 2021:

Application mappings failing using relative file paths in Adobe ColdFusion.

As you can see, in Adobe ColdFusion 2021 (and historical versions of ColdFusion), the relative paths within the Application.cfc are not relative to the "application root", they are relative to the "server root". This is why - historically - I've always had to mess with the getCurrentTemplatePath() function when configuring my application mappings.

Lucee CFML has a lot of really nice developer ergonomics; one of which is its attitude towards relative file paths. In general, relative file paths "just work". They work when performing file I/O; and, as we now know, they work when configuring ColdFusion application mappings. So nice!

Want to use code from this post? Check out the license.

Reader Comments

15,902 Comments

@Julian,

Good stuff. Inheritance is always a bit tricky when it comes to Application.cfc - left a comment over on your article.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel