There are often times when it's beneficial to determine the directory path for your currently running program. Perhaps you want to use the current directory name as the destination in a CFFILE upload statement. But how do you find the name of the directory of your currently running program?
Some will know that there are a variety of CGI variables that provide this sort of info, including:
- CF_TEMPLATE_PATH, which will show the entire path and file name of the currently running program, such as e:\systemanage\production\htdocs\cff\cftips7.cfm
- PATH_TRANSLATED, which looks the same as CF_TEMPLATE_PATH, as in e:\systemanage\production\htdocs\cff\cftips7.cfm
- PATH_INFO, which will instead show the path relative to the web server on which you're running, as in /systemanage/cff/cftips7.cfm
- SCRIPT_NAME, which looks like the same as PATH_INFO, but note the reversed directory name separators (slashes), as in /systemanage/cff/cftips7.cfm
There are also a handful of CF functions that return paths, including:
- GetCurrentTemplatePath
- GetBaseTemplatePath
Notice that it's possible that there will be considerable differences in these values, depending on how your web server is configured. We'll discuss that more later. In deciding which to use to get the "current directory", we'll have to weigh our intention for using that directory name against the differences among the values returned by these variables.
Another question one may wonder is whether these values might change when the code is running inside a CFINCLUDEd program or custom tag. More on that later, too.
Extracting the Directory Name
The premise of the article is how to extract the directory name. Each of these returns both a directory and file name. You might think that in order to obtain the directory name only you'd have to resort to some tricky string handling. DON'T DO THAT!
CF offers some powerful built-in functions and one that many never learn about is GetDirectoryFromPath. Ta Da! Just what we need. Notice that we can apply this against each of these, as in:
<cfoutput>
CF_TEMPLATE_PATH=#getdirectoryfrompath(cgi.CF_TEMPLATE_PATH)#<BRt>
PATH_TRANSLATED=#getdirectoryfrompath(cgi.PATH_TRANSLATED)#<BRt>
PATH_INFO=#getdirectoryfrompath(cgi.PATH_INFO)#<BRt>
SCRIPT_NAME=#getdirectoryfrompath(cgi.SCRIPT_NAME)#
</cfoutputt>
The answer (on my system) might be:
CF_TEMPLATE_PATH=e:\systemanage\production\htdocs\cff\
PATH_TRANSLATED=e:\systemanage\production\htdocs\cff\
PATH_INFO=/bob
SCRIPT_NAME=/bob
Again, look closely. The first two appear usable. The last two are challenges. What's up with the "/\" at the end? Well, the function seems to be oriented more to working on Windows systems, and also not on URL paths. Windows uses the \ for directory separators while Unix and URL's use /. The function doesn't recognize the closing / and therefore tacks on the closing \ (whereas it doesn't do that for the paths using the Windows format).
So one conclusion right away is that, if you are looking for a quick way to get the path of the current file (on a windows system at least), use #getDirectoryFromPath(CF_TEMPLATE_PATH)#.
Getting Just the File Name
There's a corrolary function to get just the file name from a path, GetFileFromPath. It works as straightforwardly as it sounds.
What if called in CFINCLUDE or custom tag?
One thing to be aware of is that these variables do not always present the name of what you may expect to be the "currently running template". For instance, if these are used inside a CFINCLUDE template or a called custom tag, the values will all present the name of the page that the browser originally requested.
Note that this is not accurate to say "the file that did the CFINCLUDE" or "the caller of the custom tag", because if the browser requests file a.cfm, which CFINCLUDES b.cfm which includes c.cfm, the values of these variables if reported in c.cfm (and b.cfm) are all going to report values for a.cfm.
Note that it's also not accurate to say that it's the page that the user typed in as a URL, because they may ask for d.cfm which does a CFLOCATION to a.cfm. In that case, again, the variables will report a.cfm.