ColdFusion ExpandPath() And GetCurrentTemplatePath()

Posted September 21, 2006 at 3:33 PM by Ben Nadel

Tags: ColdFusion

One of the things that always get's me is the fact that in ColdFusion, the ExpandPath() method expands the path of the base path. I would say 95% of the time, this doesn't matter, but the other 5% of the time, I end putting stuff in the wrong directories. In my head, it just makes sense that ExpandPath() should expand the current template path since that is the one calling the code (just how the CFInclude template attribute works).

When I do need to expand the current path, not the base one, I just use the GetCurrentTemplatePath(). And, since expand path is meant to add to a directory, I get the directory from the returned path:

  • <!--- Get expanded path of the BASE path. --->
  • <cfset strPath = ExpandPath( "./" ) />
  •  
  • <!--- Get the expanded path of the CURRENT template path. --->
  • <cfset strPath = GetDirectoryFromPath(
  • GetCurrentTemplatePath()
  • ) />

Assuming that we have the current directory structure:

sites
..test
....index.cfm
....sub
......test.cfm

and that our CGI.script_name points us to the page "index.cfm" but the code is being executed by the CFIncluded page, test.cfm, the first path would be:

D:\sites\test\

and the second path would be:

D:\sites\test\sub\

So anyway, just keep that in mind. We use CFIncludes so much in ColdFusion that I feel it easy to make this mistake.



Reader Comments

Oct 20, 2008 at 6:27 AM // reply »
5 Comments

Thanks Ben - your Blog has to be the most useful resource out there when it comes to CF Quirks - I remember reading this entry a couple of years back - first port of call when I needed to do this...


Oct 22, 2008 at 7:30 AM // reply »
10,640 Comments

@Dan,

I am always happy to hear that I have provided some value - thanks.


Dec 18, 2009 at 11:10 AM // reply »
8 Comments

Hopefully this tip will help someone down the road too, or maybe someone can enlighten me as to the "right" way to code for the physical file path of an application.

I was setting the following code in the OnApplicationStart() method to set the application's physical file path (http://mydomain.com/myApplication):

<cfset application.rootpath = expandPath('./')>

The application uses index.cfm as a "controller" (i.e.index.cfm?disp=thispage) so I THOUGHT it would set the path relative to the root of the application (C:\inetpub\wwwroot\mydomain\myApplication)

Well, it does...MOST of the time....I still haven't gotten to the bottom of it, but sometimes the rootpath would get set to nested directories (C:\inetpub\wwwroot\mydomain\myApplication\middle\). I can only assume that the application would sometimes reinit when it was in the middle of processing something in the "middle" directory.

Long story short, I'm about to deploy this code fix to (hopefully) resolve the problem: <cfset application.rootpath = "#expandpath('/')##application.applicationname#\"> . The application.applicationname is the same as the "myApplication" directory, so I'm hopeful that this will work....at least my three test runs worked..lol

With any luck, all this code will actually show up so its readable on Ben's blog :)


Jan 5, 2010 at 9:00 AM // reply »
10,640 Comments

@Dan,

The strategy that I have found to be very helpful is using:

getDirectoryFromPath( getCurrentTemplatePath() )

... inside of Application.cfc. Since you always know where the Application.cfc file lives, you know you can get the root directory by stripping off "Application.cfc" from the current template path (which is Application.cfc).


Mar 26, 2010 at 1:06 PM // reply »
6 Comments

Here is a neat little script that gets just the current file name, no url variables or directories. I found that all the other examples return subdirectories and url info or the cfincluded file name. I just wanted the .cfm filename for writing log files.

#right(cgi.script_name, find('/', reverse(cgi.script_name), 1) - 1)#


Mar 26, 2010 at 1:41 PM // reply »
10,640 Comments

@Erik,

getDirectoryFromPath() has a sibling function, getFileFromPath() that should help make that even easier:

#getFileFromPath( cgi.script_name )#

... should return the file name from the script name (or any other slash-delimited string).


Nov 5, 2010 at 6:49 PM // reply »
4 Comments

Ok I'm been trying to fiqure this out for a long time.

I'm trying to get my structure organized. Say I have this

Root
css.css
Index.cfm
..Includes(Folder)
Header.cfm
Footer.cfm
..Test(folder)
test1.cfm

I'm trying to use header.cfm in multiple sub files of the root via cfinclude. But my css etc doesn't follow in the header.cfm depending on the location of file when I call the include.

So on my header.cfm I have
<link href="general.css" rel="stylesheet" type="text/css">

so index.cfm works great.

but on /test/test1.cfm it doesn't apply css because path is still

<link href="general.css" rel="stylesheet" type="text/css">

Am I going about this wrong? Is there a solution to expand the header.cfm pased on the callings page location.

Is the the industry standard to organizing files?

Thanks


Nov 7, 2010 at 7:44 PM // reply »
10,640 Comments

@Mike,

I think you are getting two different types of pathing mixed up. There is the pathing on the server, and then there is the pathing in the browser. On the server, you can use things like expandPath() and getCurrentTemplatePath() and getBaseTemplatePath() and a number of other things to deal with how files are related on the server-side.

CSS, however, is a concern of the browser. The URL that you provide for your CSS file is one that the browser has to make *back* to the server after the initial page has been pushed to the client. The Browser has no concept of the internal Include-structure on the server; as such, there is not inherent relationship between your includes and your CSS files.

When you define your CSS URLs, they need to be relevant to the browser, not the include. Typically, you can either make linked assets like this (CSS, Javascript, Images, etc) always point to the root, example:

/css.css

... or you can create paths relative to the page you are currently viewing, example:

../css.css

... which goes UP one directory to get to the CSS.

I personally prefer the "../../" style approach as it can be generated dynamically without hard-coding any logic in the application.

Check out this post:

http://www.bennadel.com/blog/1655-Ask-Ben-Dynamic-Web-Root-And-Site-URL-Calculations-In-Application-cfc.htm

This will explain the matter a bit better.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »