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

ExpandPath() Works With ColdFusion's Per-Application Mappings

By
Published in Comments (4)

I don't use ColdFusion's expandPath() function very much. Sure, I'll use it in a demo when I want to just "get it done;" but, I rarely use it in any production code. I don't completely understand how expandPath() works, which has lead to invalid file paths and broken sites. That said, I'm trying to learn more about the expandPath() function; and, I'm pretty excited to find out that it works well with ColdFusion's per-application mappings.

In the past, I've used the expandPath() function almost exclusively with relative file paths which were relative to the current URL. This means that a single expandPath() expression (in the Application.cfc file, for example) can have a different outcome depending on which URL is currently being accessed. This is typically why I don't use expandPath() in production.

As of ColdFusion MX, however, the expandPath() function can accept absolute URLs. And this is where the per-application mappings come into play. expandPath() will resolve paths using mappings defined within the Application.cfc ColdFusion framework components.

To test this, I created a few mappings in my Application.cfc file:

<cfscript>

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

	// Define the application settings.
	this.name = hash( getCurrentTemplatePath() );
	this.applicationTimeout = createTimeSpan( 0, 0, 5, 0 );

	// Configure the mappings. Notethat Bar is a sub-directory of
	// Foo, which is a subdirectory of App.
	this.directory = getDirectoryFromPath( getCurrentTemplatePath() );
	this.mappings[ "/app" ] = this.directory;
	this.mappings[ "/foo" ] = "#this.directory#foo/";
	this.mappings[ "/bar" ] = "#this.directory#foo/bar/";


	// No matter what CFM file is requested, inlucde the root index.
	public void function onRequest( required string template ) {

		include "./index.cfm";

	}

}

</cfscript>

Then, I accessed the following file from a "sub/sub/" directory:

<cfoutput>

	Expand Relative:<br /> #expandPath( "~.htm" )#<br />
	<br />

	Expand App:<br /> #expandPath( "/app/~.htm" )#<br />
	<br />

	Expand Foo:<br /> #expandPath( "/foo/~.htm" )#<br />
	<br />

	Expand Bar:<br /> #expandPath( "/bar/~.htm" )#<br />
	<br />

	Expand Root:<br /> #expandPath( "/~.htm" )#<br />
	<br />

</cfoutput>

My web-application is located at the following file system location:

**/Sites/bennadel.com/testing/expand-path/**Application.cfc

... and when I access the above index file (via, the "sub/sub/" directory), I get the following page output:

Expand Relative:
/Sites/bennadel.com/testing/expand-path/sub/sub/~.htm

Expand App:
/Sites/bennadel.com/testing/expand-path/~.htm

Expand Foo:
/Sites/bennadel.com/testing/expand-path/foo/~.htm

Expand Bar:
/Sites/bennadel.com/testing/expand-path/foo/bar/~.htm

Expand Root:
/Sites/bennadel.com/~.htm

As you can see, the expandPath() function correctly resolved the absolute paths defined by the ColdFusion per-application mappings, "/app", "/foo", and "/bar". The relative file path (the first example) continues to resolve relative to the current "sub/sub/" URL.

NOTE: Notice that resolving the "/" path in the last example resolved to the root of my Apache VirtualHost entry. I would avoid using the "/" path without a per-application mapping as I believe that I've seen this behave inconsistently across different J2EE servers. I'm on JRUN.

The fact that expandPath() works well with ColdFusion's per-application mappings definitely makes me feel differently about using expandPath() in production! That said, I would still avoid using it in the Application.cfc pseudo-constructor as the per-application mappings don't take effect until you get into the ColdFusion application event handlers (ex, onApplicationStart, onRequestStart).

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

Reader Comments

11 Comments

One thing to be careful about expand path is, it doesn't work if the file or directory doesn't exist. It doesn't throw error, but it returns wrong path. So, something like this fileExits(expandPath('/mydir/myfile')) may or may not work.

15,902 Comments

@Sumit,

That sound scary :)

@Henry,

I'd be careful there, I *believe* the documentation says that it may be funky with virtual directories:

This function does not reliably use virtual mappings that are defined in IIS, Apache, or other web servers.

I don't know very much about servers and how they work; so just be careful :)

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